diff --git a/src/Tgstation.Server.Host/Components/Engine/ByondInstallerBase.cs b/src/Tgstation.Server.Host/Components/Engine/ByondInstallerBase.cs index 40fbde1a40..e02c109e6b 100644 --- a/src/Tgstation.Server.Host/Components/Engine/ByondInstallerBase.cs +++ b/src/Tgstation.Server.Host/Components/Engine/ByondInstallerBase.cs @@ -74,29 +74,30 @@ namespace Tgstation.Server.Host.Components.Engine } /// - public override IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask) + public override ValueTask CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken) { CheckVersionValidity(version); var installationIOManager = new ResolvingIOManager(IOManager, path); var supportsMapThreads = version.Version >= MapThreadsVersion; - return new ByondInstallation( - installationIOManager, - installationTask, - version, - installationIOManager.ResolvePath( - installationIOManager.ConcatPath( - ByondBinPath, - GetDreamDaemonName( - version.Version!, - out var supportsCli))), - installationIOManager.ResolvePath( - installationIOManager.ConcatPath( - ByondBinPath, - DreamMakerName)), - supportsCli, - supportsMapThreads); + return ValueTask.FromResult( + new ByondInstallation( + installationIOManager, + installationTask, + version, + installationIOManager.ResolvePath( + installationIOManager.ConcatPath( + ByondBinPath, + GetDreamDaemonName( + version.Version!, + out var supportsCli))), + installationIOManager.ResolvePath( + installationIOManager.ConcatPath( + ByondBinPath, + DreamMakerName)), + supportsCli, + supportsMapThreads)); } /// diff --git a/src/Tgstation.Server.Host/Components/Engine/DelegatingEngineInstaller.cs b/src/Tgstation.Server.Host/Components/Engine/DelegatingEngineInstaller.cs index c24eee3e8b..5b3cc20c36 100644 --- a/src/Tgstation.Server.Host/Components/Engine/DelegatingEngineInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Engine/DelegatingEngineInstaller.cs @@ -33,8 +33,8 @@ namespace Tgstation.Server.Host.Components.Engine => Task.WhenAll(delegatedInstallers.Values.Select(installer => installer.CleanCache(cancellationToken))); /// - public IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask) - => DelegateCall(version, installer => installer.CreateInstallation(version, path, installationTask)); + public ValueTask CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken) + => DelegateCall(version, installer => installer.CreateInstallation(version, path, installationTask, cancellationToken)); /// public ValueTask DownloadVersion(EngineVersion version, JobProgressReporter jobProgressReporter, CancellationToken cancellationToken) diff --git a/src/Tgstation.Server.Host/Components/Engine/EngineInstallerBase.cs b/src/Tgstation.Server.Host/Components/Engine/EngineInstallerBase.cs index 6ca2b94030..30329edd34 100644 --- a/src/Tgstation.Server.Host/Components/Engine/EngineInstallerBase.cs +++ b/src/Tgstation.Server.Host/Components/Engine/EngineInstallerBase.cs @@ -40,7 +40,7 @@ namespace Tgstation.Server.Host.Components.Engine } /// - public abstract IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask); + public abstract ValueTask CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken); /// public abstract Task CleanCache(CancellationToken cancellationToken); diff --git a/src/Tgstation.Server.Host/Components/Engine/EngineManager.cs b/src/Tgstation.Server.Host/Components/Engine/EngineManager.cs index 113a0d249b..76885286cd 100644 --- a/src/Tgstation.Server.Host/Components/Engine/EngineManager.cs +++ b/src/Tgstation.Server.Host/Components/Engine/EngineManager.cs @@ -337,7 +337,8 @@ namespace Tgstation.Server.Host.Components.Engine try { - AddInstallationContainer(version, path, Task.CompletedTask); + var installation = await engineInstaller.CreateInstallation(version, path, Task.CompletedTask, cancellationToken); + AddInstallationContainer(installation); logger.LogDebug("Added detected BYOND version {versionKey}...", version); } catch (Exception ex) @@ -410,6 +411,13 @@ namespace Tgstation.Server.Host.Components.Engine IEngineInstallation installation; EngineExecutableLock installLock; bool installedOrInstalling; + + var potentialInstallation = await engineInstaller.CreateInstallation( + version, + ioManager.ResolvePath(version.ToString()), + ourTcs.Task, + cancellationToken); + lock (installedVersions) { if (customVersionStream != null) @@ -429,10 +437,7 @@ namespace Tgstation.Server.Host.Components.Engine if (!allowInstallation) throw new InvalidOperationException($"Engine version {version} not installed!"); - installationContainer = AddInstallationContainer( - version, - ioManager.ResolvePath(version.ToString()), - ourTcs.Task); + installationContainer = AddInstallationContainer(potentialInstallation); } else installationContainer = installationContainerNullable!; @@ -616,18 +621,14 @@ namespace Tgstation.Server.Host.Components.Engine /// /// Create and add a new to . /// - /// The being added. - /// The path to the installation. - /// The representing the installation process. - /// The new . - ReferenceCountingContainer AddInstallationContainer(EngineVersion version, string installPath, Task installationTask) + /// The being added. + /// A new for the /. + ReferenceCountingContainer AddInstallationContainer(IEngineInstallation installation) { - var installation = engineInstaller.CreateInstallation(version, installPath, installationTask); - var installationContainer = new ReferenceCountingContainer(installation); lock (installedVersions) - installedVersions.Add(version, installationContainer); + installedVersions.Add(installation.Version, installationContainer); return installationContainer; } diff --git a/src/Tgstation.Server.Host/Components/Engine/IEngineInstaller.cs b/src/Tgstation.Server.Host/Components/Engine/IEngineInstaller.cs index 0df793e219..1e943f9759 100644 --- a/src/Tgstation.Server.Host/Components/Engine/IEngineInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Engine/IEngineInstaller.cs @@ -17,8 +17,9 @@ namespace Tgstation.Server.Host.Components.Engine /// The of the installation. /// The path to the installation. /// The representing the installation process for the installation. - /// The . - IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask); + /// The for the operation. + /// A resulting in the . + ValueTask CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken); /// /// Download a given engine . diff --git a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs index e7fbd9baa6..b8f5e7f877 100644 --- a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs +++ b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs @@ -60,30 +60,46 @@ namespace Tgstation.Server.Host.Components.Engine /// readonly IAbstractHttpClientFactory httpClientFactory; + /// + /// Path to the Robust.Server.dll. + /// + readonly string serverDllPath; + + /// + /// Path to the DMCompiler.dll. + /// + readonly string compilerDllPath; + /// /// Initializes a new instance of the class. /// /// The for the . /// The value of . /// The value of . - /// The value of . - /// The value of . + /// The path to the dotnet executable. + /// The value of . + /// The value of . /// The value of . /// The value of . public OpenDreamInstallation( IIOManager installationIOManager, IAsyncDelayer asyncDelayer, IAbstractHttpClientFactory httpClientFactory, - string serverExePath, - string compilerExePath, + string dotnetPath, + string serverDllPath, + string compilerDllPath, Task installationTask, EngineVersion version) : base(installationIOManager) { this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer)); this.httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); - ServerExePath = serverExePath ?? throw new ArgumentNullException(nameof(serverExePath)); - CompilerExePath = compilerExePath ?? throw new ArgumentNullException(nameof(compilerExePath)); + + ServerExePath = dotnetPath ?? throw new ArgumentNullException(nameof(dotnetPath)); + CompilerExePath = dotnetPath; + + this.serverDllPath = serverDllPath ?? throw new ArgumentNullException(nameof(serverDllPath)); + this.compilerDllPath = compilerDllPath ?? throw new ArgumentNullException(nameof(compilerDllPath)); InstallationTask = installationTask ?? throw new ArgumentNullException(nameof(installationTask)); Version = version ?? throw new ArgumentNullException(nameof(version)); @@ -107,7 +123,7 @@ namespace Tgstation.Server.Host.Components.Engine var parametersString = EncodeParameters(parameters, launchParameters); - var arguments = $"--cvar {(logFilePath != null ? $"log.path=\"{InstallationIOManager.GetDirectoryName(logFilePath)}\" --cvar log.format=\"{InstallationIOManager.GetFileName(logFilePath)}\"" : "log.enabled=false")} --cvar watchdog.token={accessIdentifier} --cvar log.runtimelog=false --cvar net.port={launchParameters.Port!.Value} --cvar opendream.topic_port={launchParameters.OpenDreamTopicPort!.Value} --cvar opendream.world_params=\"{parametersString}\" --cvar opendream.json_path=\"./{dmbProvider.DmbName}\""; + var arguments = $"{serverDllPath} --cvar {(logFilePath != null ? $"log.path=\"{InstallationIOManager.GetDirectoryName(logFilePath)}\" --cvar log.format=\"{InstallationIOManager.GetFileName(logFilePath)}\"" : "log.enabled=false")} --cvar watchdog.token={accessIdentifier} --cvar log.runtimelog=false --cvar net.port={launchParameters.Port!.Value} --cvar opendream.topic_port={launchParameters.OpenDreamTopicPort!.Value} --cvar opendream.world_params=\"{parametersString}\" --cvar opendream.json_path=\"./{dmbProvider.DmbName}\""; return arguments; } @@ -119,7 +135,7 @@ namespace Tgstation.Server.Host.Components.Engine else additionalArguments = $"{additionalArguments.Trim()} "; - return $"--suppress-unimplemented --notices-enabled {additionalArguments}\"{dmePath ?? throw new ArgumentNullException(nameof(dmePath))}\""; + return $"{compilerDllPath} --suppress-unimplemented --notices-enabled {additionalArguments}\"{dmePath ?? throw new ArgumentNullException(nameof(dmePath))}\""; } /// diff --git a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs index f37c4489b1..c24619d084 100644 --- a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs @@ -118,14 +118,20 @@ namespace Tgstation.Server.Host.Components.Engine public override Task CleanCache(CancellationToken cancellationToken) => Task.CompletedTask; /// - public override IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask) + public override async ValueTask CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken) { CheckVersionValidity(version); GetExecutablePaths(path, out var serverExePath, out var compilerExePath); + + var dotnetPath = await DotnetHelper.GetDotnetPath(platformIdentifier, IOManager, cancellationToken); + if (dotnetPath == null) + throw new JobException("Failed to find dotnet path!"); + return new OpenDreamInstallation( new ResolvingIOManager(IOManager, path), asyncDelayer, httpClientFactory, + dotnetPath, serverExePath, compilerExePath, installationTask, @@ -370,21 +376,19 @@ namespace Tgstation.Server.Host.Components.Engine /// The path to the DMCompiler executable. protected void GetExecutablePaths(string installationPath, out string serverExePath, out string compilerExePath) { - var exeExtension = platformIdentifier.IsWindows - ? ".exe" - : String.Empty; + const string DllExtension = ".dll"; serverExePath = IOManager.ConcatPath( installationPath, BinDir, ServerDir, - $"Robust.Server{exeExtension}"); + $"Robust.Server{DllExtension}"); compilerExePath = IOManager.ConcatPath( installationPath, BinDir, InstallationCompilerDirectory, - $"DMCompiler{exeExtension}"); + $"DMCompiler{DllExtension}"); } } }