diff --git a/build/Version.props b/build/Version.props
index 3d8d79e696..05c5365352 100644
--- a/build/Version.props
+++ b/build/Version.props
@@ -10,7 +10,7 @@
12.0.0
13.0.0
6.6.0
- 5.6.1
+ 5.7.0
1.4.0
1.2.1
2.0.0
diff --git a/src/DMAPI/tgs/v5/__interop_version.dm b/src/DMAPI/tgs/v5/__interop_version.dm
index 5d3d491a73..83420d130a 100644
--- a/src/DMAPI/tgs/v5/__interop_version.dm
+++ b/src/DMAPI/tgs/v5/__interop_version.dm
@@ -1 +1 @@
-"5.6.1"
+"5.7.0"
diff --git a/src/DMAPI/tgs/v5/_defines.dm b/src/DMAPI/tgs/v5/_defines.dm
index f973338daa..b4557c562c 100644
--- a/src/DMAPI/tgs/v5/_defines.dm
+++ b/src/DMAPI/tgs/v5/_defines.dm
@@ -8,7 +8,6 @@
#define DMAPI5_TOPIC_REQUEST_LIMIT 65528
#define DMAPI5_TOPIC_RESPONSE_LIMIT 65529
-#define DMAPI5_BRIDGE_COMMAND_PORT_UPDATE 0
#define DMAPI5_BRIDGE_COMMAND_STARTUP 1
#define DMAPI5_BRIDGE_COMMAND_PRIME 2
#define DMAPI5_BRIDGE_COMMAND_REBOOT 3
@@ -18,6 +17,7 @@
#define DMAPI5_PARAMETER_ACCESS_IDENTIFIER "accessIdentifier"
#define DMAPI5_PARAMETER_CUSTOM_COMMANDS "customCommands"
+#define DMAPI5_PARAMETER_TOPIC_PORT "topicPort"
#define DMAPI5_CHUNK "chunk"
#define DMAPI5_CHUNK_PAYLOAD "payload"
diff --git a/src/DMAPI/tgs/v5/api.dm b/src/DMAPI/tgs/v5/api.dm
index 34cc43f876..cb8a2f11f7 100644
--- a/src/DMAPI/tgs/v5/api.dm
+++ b/src/DMAPI/tgs/v5/api.dm
@@ -38,7 +38,7 @@
var/datum/tgs_version/api_version = ApiVersion()
version = null
- var/list/bridge_response = Bridge(DMAPI5_BRIDGE_COMMAND_STARTUP, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = api_version.raw_parameter, DMAPI5_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands()))
+ var/list/bridge_response = Bridge(DMAPI5_BRIDGE_COMMAND_STARTUP, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = api_version.raw_parameter, DMAPI5_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands(), DMAPI5_PARAMETER_TOPIC_PORT = GetTopicPort()))
if(!istype(bridge_response))
TGS_ERROR_LOG("Failed initial bridge request!")
return FALSE
@@ -100,6 +100,13 @@
initialized = TRUE
return TRUE
+/datum/tgs_api/v5/proc/GetTopicPort()
+#if defined(OPENDREAM) && defined(OPENDREAM_TOPIC_PORT_EXISTS)
+ return "[world.opendream_topic_port]"
+#else
+ return null
+#endif
+
/datum/tgs_api/v5/proc/RequireInitialBridgeResponse()
TGS_DEBUG_LOG("RequireInitialBridgeResponse()")
var/logged = FALSE
diff --git a/src/DMAPI/tgs/v5/topic.dm b/src/DMAPI/tgs/v5/topic.dm
index d7d4712138..40ab80e465 100644
--- a/src/DMAPI/tgs/v5/topic.dm
+++ b/src/DMAPI/tgs/v5/topic.dm
@@ -175,6 +175,7 @@
var/list/reattach_response = TopicResponse(error_message)
reattach_response[DMAPI5_PARAMETER_CUSTOM_COMMANDS] = ListCustomCommands()
+ reattach_response[DMAPI5_PARAMETER_TOPIC_PORT] = GetTopicPort()
return reattach_response
if(DMAPI5_TOPIC_COMMAND_SEND_CHUNK)
diff --git a/src/DMAPI/tgs/v5/undefs.dm b/src/DMAPI/tgs/v5/undefs.dm
index c679737dfc..f579cbefb7 100644
--- a/src/DMAPI/tgs/v5/undefs.dm
+++ b/src/DMAPI/tgs/v5/undefs.dm
@@ -8,7 +8,6 @@
#undef DMAPI5_TOPIC_REQUEST_LIMIT
#undef DMAPI5_TOPIC_RESPONSE_LIMIT
-#undef DMAPI5_BRIDGE_COMMAND_PORT_UPDATE
#undef DMAPI5_BRIDGE_COMMAND_STARTUP
#undef DMAPI5_BRIDGE_COMMAND_PRIME
#undef DMAPI5_BRIDGE_COMMAND_REBOOT
@@ -18,6 +17,7 @@
#undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER
#undef DMAPI5_PARAMETER_CUSTOM_COMMANDS
+#undef DMAPI5_PARAMETER_TOPIC_PORT
#undef DMAPI5_CHUNK
#undef DMAPI5_CHUNK_PAYLOAD
diff --git a/src/Tgstation.Server.Api/Models/Internal/DreamDaemonLaunchParameters.cs b/src/Tgstation.Server.Api/Models/Internal/DreamDaemonLaunchParameters.cs
index b563d95585..b21ce258ff 100644
--- a/src/Tgstation.Server.Api/Models/Internal/DreamDaemonLaunchParameters.cs
+++ b/src/Tgstation.Server.Api/Models/Internal/DreamDaemonLaunchParameters.cs
@@ -9,21 +9,21 @@ namespace Tgstation.Server.Api.Models.Internal
public class DreamDaemonLaunchParameters
{
///
- /// If the BYOND web client can be used to connect to the game server.
+ /// If the BYOND web client can be used to connect to the game server. No-op for .
///
[Required]
[ResponseOptions]
public bool? AllowWebClient { get; set; }
///
- /// If -profile is passed in on the DreamDaemon command line.
+ /// If -profile is passed in on the DreamDaemon command line. No-op for .
///
[Required]
[ResponseOptions]
public bool? StartProfiler { get; set; }
///
- /// The level of DreamDaemon.
+ /// The level of DreamDaemon. No-op for .
///
[Required]
[ResponseOptions]
@@ -31,7 +31,7 @@ namespace Tgstation.Server.Api.Models.Internal
public DreamDaemonVisibility? Visibility { get; set; }
///
- /// The level of DreamDaemon.
+ /// The level of DreamDaemon. No-op for .
///
[Required]
[ResponseOptions]
@@ -92,7 +92,7 @@ namespace Tgstation.Server.Api.Models.Internal
public bool? LogOutput { get; set; }
///
- /// If DreamDaemon supports it, the value added as the -map-threads parameter. 0 uses the default BYOND value.
+ /// If DreamDaemon supports it, the value added as the -map-threads parameter. 0 uses the default BYOND value. No-op for .
///
[Required]
[ResponseOptions]
diff --git a/src/Tgstation.Server.Host/Components/Deployment/DmbProvider.cs b/src/Tgstation.Server.Host/Components/Deployment/DmbProvider.cs
index 554cc28cdd..2b58ba17c0 100644
--- a/src/Tgstation.Server.Host/Components/Deployment/DmbProvider.cs
+++ b/src/Tgstation.Server.Host/Components/Deployment/DmbProvider.cs
@@ -6,19 +6,16 @@ using Tgstation.Server.Host.IO;
namespace Tgstation.Server.Host.Components.Deployment
{
///
- sealed class DmbProvider : IDmbProvider
+ sealed class DmbProvider : DmbProviderBase, IDmbProvider
{
///
- public string DmbName => String.Concat(CompileJob.DmeName, DreamMaker.DmbExtension);
+ public override string Directory => ioManager.ResolvePath(CompileJob.DirectoryName.ToString() + directoryAppend);
///
- public string Directory => ioManager.ResolvePath(CompileJob.DirectoryName.ToString() + directoryAppend);
+ public override Models.CompileJob CompileJob { get; }
///
- public Models.CompileJob CompileJob { get; }
-
- ///
- public ByondVersion ByondVersion { get; }
+ public override ByondVersion ByondVersion { get; }
///
/// The for the .
@@ -53,9 +50,9 @@ namespace Tgstation.Server.Host.Components.Deployment
}
///
- public void Dispose() => onDispose?.Invoke();
+ public override void Dispose() => onDispose?.Invoke();
///
- public void KeepAlive() => onDispose = null;
+ public override void KeepAlive() => onDispose = null;
}
}
diff --git a/src/Tgstation.Server.Host/Components/Deployment/DmbProviderBase.cs b/src/Tgstation.Server.Host/Components/Deployment/DmbProviderBase.cs
new file mode 100644
index 0000000000..ea792bd23d
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Deployment/DmbProviderBase.cs
@@ -0,0 +1,37 @@
+using System;
+
+using Tgstation.Server.Api.Models;
+using Tgstation.Server.Api.Models.Internal;
+using Tgstation.Server.Host.Models;
+
+namespace Tgstation.Server.Host.Components.Deployment
+{
+ ///
+ abstract class DmbProviderBase : IDmbProvider
+ {
+ ///
+ public string DmbName => String.Concat(
+ CompileJob.DmeName,
+ ByondVersion.Engine.Value switch
+ {
+ EngineType.Byond => ".dmb",
+ EngineType.OpenDream => ".json",
+ _ => throw new InvalidOperationException($"Invalid EngineType: {ByondVersion.Engine.Value}"),
+ });
+
+ ///
+ public abstract string Directory { get; }
+
+ ///
+ public abstract Models.CompileJob CompileJob { get; }
+
+ ///
+ public abstract ByondVersion ByondVersion { get; }
+
+ ///
+ public abstract void Dispose();
+
+ ///
+ public abstract void KeepAlive();
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs
index 8dd925f812..cc7c03b001 100644
--- a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs
+++ b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs
@@ -30,11 +30,6 @@ namespace Tgstation.Server.Host.Components.Deployment
///
sealed class DreamMaker : IDreamMaker
{
- ///
- /// Extension for .dmbs.
- ///
- public const string DmbExtension = ".dmb";
-
///
/// Extension for .dmes.
///
@@ -805,7 +800,6 @@ namespace Tgstation.Server.Host.Components.Deployment
ApiValidationStatus validationStatus;
using (var provider = new TemporaryDmbProvider(
ioManager.ResolvePath(job.DirectoryName.ToString()),
- String.Concat(job.DmeName, DmbExtension),
job,
byondLock.Version))
await using (var controller = await sessionControllerFactory.LaunchNew(provider, byondLock, launchParameters, true, cancellationToken))
diff --git a/src/Tgstation.Server.Host/Components/Deployment/TemporaryDmbProvider.cs b/src/Tgstation.Server.Host/Components/Deployment/TemporaryDmbProvider.cs
index 5ecc6b9670..a94efe35ed 100644
--- a/src/Tgstation.Server.Host/Components/Deployment/TemporaryDmbProvider.cs
+++ b/src/Tgstation.Server.Host/Components/Deployment/TemporaryDmbProvider.cs
@@ -7,41 +7,36 @@ namespace Tgstation.Server.Host.Components.Deployment
///
/// Temporary .
///
- sealed class TemporaryDmbProvider : IDmbProvider
+ sealed class TemporaryDmbProvider : DmbProviderBase
{
///
- public string DmbName { get; }
+ public override string Directory { get; }
///
- public string Directory { get; }
+ public override Models.CompileJob CompileJob { get; }
///
- public Models.CompileJob CompileJob { get; }
-
- ///
- public ByondVersion ByondVersion { get; }
+ public override ByondVersion ByondVersion { get; }
///
/// Initializes a new instance of the class.
///
/// The value of .
- /// The value of .
/// The value of .
/// The value of .
- public TemporaryDmbProvider(string directory, string dmb, Models.CompileJob compileJob, ByondVersion byondVersion)
+ public TemporaryDmbProvider(string directory, Models.CompileJob compileJob, ByondVersion byondVersion)
{
- DmbName = dmb ?? throw new ArgumentNullException(nameof(dmb));
Directory = directory ?? throw new ArgumentNullException(nameof(directory));
CompileJob = compileJob ?? throw new ArgumentNullException(nameof(compileJob));
ByondVersion = byondVersion ?? throw new ArgumentNullException(nameof(byondVersion));
}
///
- public void Dispose()
+ public override void Dispose()
{
}
///
- public void KeepAlive() => throw new NotSupportedException();
+ public override void KeepAlive() => throw new NotSupportedException();
}
}
diff --git a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs
index 5a3d04d6d2..6d1fc3377a 100644
--- a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs
+++ b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs
@@ -1,6 +1,8 @@
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;
@@ -34,21 +36,23 @@ namespace Tgstation.Server.Host.Components.Engine
///
/// Initializes a new instance of the class.
///
+ /// The value of .
+ /// The value of .
/// The value of .
/// The value of .
public OpenDreamInstallation(
+ string serverExePath,
+ string compilerExePath,
Task installationTask,
ByondVersion version)
{
+ ServerExePath = serverExePath ?? throw new ArgumentNullException(nameof(serverExePath));
+ CompilerExePath = compilerExePath ?? throw new ArgumentNullException(nameof(compilerExePath));
InstallationTask = installationTask ?? throw new ArgumentNullException(nameof(installationTask));
ArgumentNullException.ThrowIfNull(version);
if (version.Engine.Value != EngineType.OpenDream)
throw new ArgumentException($"Invalid EngineType: {version.Engine.Value}", nameof(version));
-
- Version = version ?? throw new ArgumentNullException(nameof(version));
-
- throw new NotImplementedException();
}
///
@@ -58,14 +62,33 @@ namespace Tgstation.Server.Host.Components.Engine
ArgumentNullException.ThrowIfNull(parameters);
ArgumentNullException.ThrowIfNull(launchParameters);
- throw new NotImplementedException();
+ var parametersString = String.Join(';', parameters.Select(kvp => $"{kvp.Key}={kvp.Value}"));
+
+ 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 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)
- {
- ArgumentNullException.ThrowIfNull(dmePath);
- throw new NotImplementedException();
- }
+ => $"--suppress-unimplemented --verbose --notices-enabled {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 9eb60f0dfe..3021238614 100644
--- a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs
+++ b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs
@@ -23,10 +23,15 @@ namespace Tgstation.Server.Host.Components.Engine
///
sealed class OpenDreamInstaller : EngineInstallerBase
{
+ ///
+ /// The name of the subdirectory used to store the server and compiler binaries.
+ ///
+ const string InstallationBinDirectory = "bin";
+
///
/// The name of the subdirectory used for the 's copy.
///
- private const string InstallationRepositorySubDirectory = "SourceRepo";
+ const string InstallationSourceSubDirectory = "TgsSourceSubdir";
///
protected override EngineType TargetEngineType => EngineType.OpenDream;
@@ -82,7 +87,21 @@ namespace Tgstation.Server.Host.Components.Engine
public override IEngineInstallation CreateInstallation(ByondVersion version, Task installationTask)
{
CheckVersionValidity(version);
- return new OpenDreamInstallation(installationTask, version);
+ var binPathForVersion = IOManager.ConcatPath(version.ToString(), InstallationBinDirectory);
+
+ var exeExtension = platformIdentifier.IsWindows
+ ? ".exe"
+ : String.Empty;
+
+ return new OpenDreamInstallation(
+ IOManager.ConcatPath(
+ binPathForVersion,
+ $"OpenDreamServer{exeExtension}"),
+ IOManager.ConcatPath(
+ binPathForVersion,
+ $"DMCompiler{exeExtension}"),
+ installationTask,
+ version);
}
///
@@ -135,7 +154,7 @@ namespace Tgstation.Server.Host.Components.Engine
version.SourceCommittish = repo.Head;
- return new RepositoryEngineInstallationData(IOManager, repo, InstallationRepositorySubDirectory);
+ return new RepositoryEngineInstallationData(IOManager, repo, InstallationSourceSubDirectory);
}
catch
{
@@ -149,6 +168,40 @@ namespace Tgstation.Server.Host.Components.Engine
{
CheckVersionValidity(version);
ArgumentNullException.ThrowIfNull(installPath);
+ var sourcePath = IOManager.ConcatPath(installPath, InstallationSourceSubDirectory);
+
+ if (!await IOManager.DirectoryExists(sourcePath, cancellationToken))
+ {
+ // a zip install that didn't come from us?
+ // we want to use the bin dir, so put everything where we expect
+ Logger.LogDebug("Correcting extraction location...");
+ var dirsTask = IOManager.GetDirectories(installPath, cancellationToken);
+ var filesTask = IOManager.GetFiles(installPath, cancellationToken);
+ var dirCreateTask = IOManager.CreateDirectory(sourcePath, cancellationToken);
+
+ await Task.WhenAll(dirsTask, filesTask, dirCreateTask);
+
+ var dirsMoveTasks = dirsTask
+ .Result
+ .Select(
+ dirPath => IOManager.MoveDirectory(
+ dirPath,
+ IOManager.ConcatPath(
+ sourcePath,
+ IOManager.GetFileName(sourcePath)),
+ cancellationToken));
+ var filesMoveTask = filesTask
+ .Result
+ .Select(
+ filePath => IOManager.MoveFile(
+ filePath,
+ IOManager.ConcatPath(
+ sourcePath,
+ IOManager.GetFileName(sourcePath)),
+ cancellationToken));
+
+ await Task.WhenAll(dirsMoveTasks.Concat(filesMoveTask));
+ }
var dotnetPaths = DotnetHelper.GetPotentialDotnetPaths(platformIdentifier.IsWindows)
.ToList();
@@ -165,11 +218,9 @@ namespace Tgstation.Server.Host.Components.Engine
var dotnetPath = dotnetPaths[selectedPathIndex];
- var repositoryPath = IOManager.ConcatPath(installPath, InstallationRepositorySubDirectory);
-
await using (var buildProcess = processExecutor.LaunchProcess(
dotnetPath,
- repositoryPath,
+ sourcePath,
"build -c Release",
null,
true,
@@ -180,18 +231,17 @@ namespace Tgstation.Server.Host.Components.Engine
throw new JobException("OpenDream build failed!");
}
- const string BinDirectory = "bin";
await IOManager.MoveDirectory(
IOManager.ConcatPath(
- repositoryPath,
- BinDirectory,
+ sourcePath,
+ InstallationBinDirectory,
"Content.Server"),
IOManager.ConcatPath(
installPath,
- BinDirectory),
+ InstallationBinDirectory),
cancellationToken);
- await IOManager.DeleteDirectory(repositoryPath, cancellationToken);
+ await IOManager.DeleteDirectory(sourcePath, cancellationToken);
}
///
diff --git a/src/Tgstation.Server.Host/Components/Interop/Bridge/BridgeCommandType.cs b/src/Tgstation.Server.Host/Components/Interop/Bridge/BridgeCommandType.cs
index ad3c227356..627d55d994 100644
--- a/src/Tgstation.Server.Host/Components/Interop/Bridge/BridgeCommandType.cs
+++ b/src/Tgstation.Server.Host/Components/Interop/Bridge/BridgeCommandType.cs
@@ -8,7 +8,7 @@
///
/// DreamDaemon notifying us of its current port and requesting a change if necessary.
///
- PortUpdate,
+ DeprecatedPortUpdate,
///
/// DreamDaemon notifying it is starting.
diff --git a/src/Tgstation.Server.Host/Components/Interop/Bridge/BridgeParameters.cs b/src/Tgstation.Server.Host/Components/Interop/Bridge/BridgeParameters.cs
index 6bd13cb72d..c1c9213063 100644
--- a/src/Tgstation.Server.Host/Components/Interop/Bridge/BridgeParameters.cs
+++ b/src/Tgstation.Server.Host/Components/Interop/Bridge/BridgeParameters.cs
@@ -17,7 +17,7 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
public BridgeCommandType? CommandType { get; set; }
///
- /// The current port for requests.
+ /// The current port for requests.
///
public ushort? CurrentPort { get; set; }
@@ -45,5 +45,10 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
/// The for requests.
///
public ChunkData Chunk { get; set; }
+
+ ///
+ /// The port that should be used to send world topics, if not the default.
+ ///
+ public ushort? TopicPort { get; set; }
}
}
diff --git a/src/Tgstation.Server.Host/Components/Session/ISessionController.cs b/src/Tgstation.Server.Host/Components/Session/ISessionController.cs
index a42186c66b..ba894c941c 100644
--- a/src/Tgstation.Server.Host/Components/Session/ISessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Session/ISessionController.cs
@@ -2,9 +2,9 @@
using System.Threading;
using System.Threading.Tasks;
+using Tgstation.Server.Api.Models.Internal;
using Tgstation.Server.Host.Components.Deployment;
using Tgstation.Server.Host.Components.Interop.Topic;
-using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.System;
namespace Tgstation.Server.Host.Components.Session
@@ -37,7 +37,12 @@ namespace Tgstation.Server.Host.Components.Session
///
/// Gets the associated with the .
///
- CompileJob CompileJob { get; }
+ Models.CompileJob CompileJob { get; }
+
+ ///
+ /// Gets the associated with the .
+ ///
+ ByondVersion ByondVersion { get; }
///
/// Gets the associated with the .
@@ -98,14 +103,6 @@ namespace Tgstation.Server.Host.Components.Session
/// A resulting in the of /world/Topic().
ValueTask SendCommand(TopicParameters parameters, CancellationToken cancellationToken);
- ///
- /// Causes the world to start listening on a .
- ///
- /// The port to change to.
- /// The for the operation.
- /// A resulting in if the operation succeeded, otherwise.
- Task SetPort(ushort newPort, CancellationToken cancellatonToken);
-
///
/// Attempts to change the current to .
///
diff --git a/src/Tgstation.Server.Host/Components/Session/SessionController.cs b/src/Tgstation.Server.Host/Components/Session/SessionController.cs
index f8a9a928f9..3802387b61 100644
--- a/src/Tgstation.Server.Host/Components/Session/SessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Session/SessionController.cs
@@ -14,6 +14,7 @@ using Newtonsoft.Json;
using Serilog.Context;
using Tgstation.Server.Api.Models;
+using Tgstation.Server.Api.Models.Internal;
using Tgstation.Server.Common.Extensions;
using Tgstation.Server.Host.Components.Chat;
using Tgstation.Server.Host.Components.Deployment;
@@ -51,6 +52,9 @@ namespace Tgstation.Server.Host.Components.Session
///
public Models.CompileJob CompileJob => ReattachInformation.Dmb.CompileJob;
+ ///
+ public ByondVersion ByondVersion => ReattachInformation.Dmb.ByondVersion;
+
///
public RebootState RebootState => ReattachInformation.RebootState;
@@ -167,11 +171,6 @@ namespace Tgstation.Server.Host.Components.Session
///
readonly object synchronizationLock;
- ///
- /// The waits on when DreamDaemon currently has it's ports closed.
- ///
- TaskCompletionSource portAssignmentTcs;
-
///
/// The that completes when DD sends a valid startup bridge request.
///
@@ -197,11 +196,6 @@ namespace Tgstation.Server.Host.Components.Session
///
volatile uint rebootBridgeRequestsProcessing;
- ///
- /// The port to assign DreamDaemon when it queries for it.
- ///
- ushort? nextPort;
-
///
/// The for the .
///
@@ -484,40 +478,6 @@ namespace Tgstation.Server.Host.Components.Session
return fullResponse;
}
- ///
- public Task SetPort(ushort port, CancellationToken cancellationToken)
- {
- CheckDisposed();
-
- if (port == 0)
- throw new ArgumentOutOfRangeException(nameof(port), port, "port must not be zero!");
-
- async Task ImmediateTopicPortChange()
- {
- var commandResult = await SendCommand(
- new TopicParameters(port),
- cancellationToken);
-
- if (commandResult?.ErrorMessage != null)
- return false;
-
- ReattachInformation.Port = port;
- return true;
- }
-
- lock (synchronizationLock)
- if (portClosedForReboot)
- {
- if (portAssignmentTcs != null)
- throw new InvalidOperationException("A port change operation is already in progress!");
- nextPort = port;
- portAssignmentTcs = new TaskCompletionSource();
- return portAssignmentTcs.Task;
- }
- else
- return ImmediateTopicPortChange();
- }
-
///
public async ValueTask SetRebootState(RebootState newRebootState, CancellationToken cancellationToken)
{
@@ -702,37 +662,8 @@ namespace Tgstation.Server.Host.Components.Session
TerminationWasRequested = true;
process.Terminate();
break;
- case BridgeCommandType.PortUpdate:
- lock (synchronizationLock)
- {
- if (!parameters.CurrentPort.HasValue)
- {
- /////UHHHH
- Logger.LogWarning("DreamDaemon sent new port command without providing it's own!");
- return BridgeError("Missing stringified port as data parameter!");
- }
-
- var currentPort = parameters.CurrentPort.Value;
- if (!nextPort.HasValue)
- ReattachInformation.Port = parameters.CurrentPort.Value; // not ready yet, so what we'll do is accept the random port DD opened on for now and change it later when we decide to
- else
- {
- // nextPort is ready, tell DD to switch to that
- // if it fails it'll kill itself
- response.NewPort = nextPort.Value;
- ReattachInformation.Port = nextPort.Value;
- nextPort = null;
-
- // we'll also get here from SetPort so complete that task
- var tmpTcs = portAssignmentTcs;
- portAssignmentTcs = null;
- tmpTcs.SetResult(true);
- }
-
- portClosedForReboot = false;
- }
-
- break;
+ case BridgeCommandType.DeprecatedPortUpdate:
+ return BridgeError("Port switching is no longer supported!");
case BridgeCommandType.Startup:
apiValidationStatus = ApiValidationStatus.BadValidationRequest;
if (parameters.Version == null)
@@ -774,6 +705,13 @@ namespace Tgstation.Server.Host.Components.Session
ReattachInformation.RuntimeInformation.ServerPort,
ReattachInformation.RuntimeInformation.ApiValidateOnly);
+ if (parameters.TopicPort.HasValue)
+ {
+ var newTopicPort = parameters.TopicPort.Value;
+ Logger.LogInformation("Server is requesting use of port {topicPort} for topic communications", newTopicPort);
+ ReattachInformation.Port = newTopicPort;
+ }
+
// Load custom commands
chatTrackingContext.CustomCommands = parameters.CustomCommands;
Interlocked.Exchange(ref startupTcs, new TaskCompletionSource()).SetResult();
@@ -816,7 +754,7 @@ namespace Tgstation.Server.Host.Components.Session
/// A new errored .
BridgeResponse BridgeError(string message)
{
- Logger.LogWarning("Bridge request chunking error: {message}", message);
+ Logger.LogWarning("Bridge request error: {message}", message);
return new BridgeResponse
{
ErrorMessage = message,
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
index fa9159527d..dc15334e75 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
@@ -255,6 +255,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
await CheckLaunchResult(Server, "Server", cancellationToken);
Server.EnableCustomChatCommands();
+
+ // persist again, because the DMAPI can say we need a different topic port (Original OD behavior)
+ // kinda hacky imo, but at least we can safely forget about this
+ if (!reattachInProgress)
+ await SessionPersistor.Save(Server.ReattachInformation, cancellationToken);
}
catch (Exception ex)
{
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs
index cdc5307352..af112dae3e 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
+using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Internal;
using Tgstation.Server.Host.Components.Chat;
using Tgstation.Server.Host.Components.Deployment;
@@ -245,6 +246,16 @@ namespace Tgstation.Server.Host.Components.Watchdog
canSeamlesslySwap = false;
}
+ if (Server.ByondVersion.Engine.Value != EngineType.Byond
+ || compileJobProvider.ByondVersion.Engine.Value != EngineType.Byond)
+ {
+ Logger.LogDebug(
+ "Not swapping to new compile job {newCompileJobId} as it or the current compile job ({oldCompileJobId}) is not using the BYOND engine. Queueing graceful restart instead...",
+ compileJobProvider.CompileJob.Id,
+ Server.CompileJob.Id);
+ canSeamlesslySwap = false;
+ }
+
if (!canSeamlesslySwap)
{
compileJobProvider.Dispose();