tgstation-server 6.14.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
SessionControllerFactory.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Globalization;
4using System.Linq;
5using System.Net.Sockets;
6using System.Text;
7using System.Threading;
8using System.Threading.Tasks;
9
10using Microsoft.Extensions.Logging;
11
12using Prometheus;
13
31
33{
36 {
40 const string DreamDaemonLogsPath = "DreamDaemonLogs";
41
46
51
56
61
66
71
76
81
86
91
96
101
106
111
116
120 readonly ILoggerFactory loggerFactory;
121
125 readonly ILogger<SessionControllerFactory> logger;
126
131
135 readonly Counter sessionsLaunched;
136
140 readonly Gauge lastSessionLaunch;
141
146
154 async ValueTask PortBindTest(ushort port, EngineType engineType, CancellationToken cancellationToken)
155 {
156 logger.LogTrace("Bind test: {port}", port);
157 try
158 {
159 // GIVE ME THE FUCKING PORT BACK WINDOWS!!!!
160 const int MaxAttempts = 5;
161 for (var i = 0; i < MaxAttempts; ++i)
162 try
163 {
164 SocketExtensions.BindTest(platformIdentifier, port, false, engineType == EngineType.OpenDream);
165 if (i > 0)
166 logger.LogDebug("Clearing the socket took {iterations} attempts :/", i + 1);
167
168 break;
169 }
170 catch (SocketException ex) when (platformIdentifier.IsWindows && ex.SocketErrorCode == SocketError.AddressAlreadyInUse && i < (MaxAttempts - 1))
171 {
172 await asyncDelayer.Delay(TimeSpan.FromSeconds(1), cancellationToken);
173 }
174 }
175 catch (SocketException ex) when (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
176 {
177 throw new JobException(ErrorCode.GameServerPortInUse, ex);
178 }
179 }
180
220 IMetricFactory metricFactory,
221 ILoggerFactory loggerFactory,
222 ILogger<SessionControllerFactory> logger,
224 Api.Models.Instance instance)
225 {
226 this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
227 this.engineManager = engineManager ?? throw new ArgumentNullException(nameof(engineManager));
228 this.topicClientFactory = topicClientFactory ?? throw new ArgumentNullException(nameof(topicClientFactory));
229 this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite));
230 this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
231 this.gameIOManager = gameIOManager ?? throw new ArgumentNullException(nameof(gameIOManager));
232 this.diagnosticsIOManager = diagnosticsIOManager ?? throw new ArgumentNullException(nameof(diagnosticsIOManager));
233 this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
234 this.networkPromptReaper = networkPromptReaper ?? throw new ArgumentNullException(nameof(networkPromptReaper));
235 this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier));
236 this.bridgeRegistrar = bridgeRegistrar ?? throw new ArgumentNullException(nameof(bridgeRegistrar));
237 this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider));
238 this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
239 this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
240 this.dotnetDumpService = dotnetDumpService ?? throw new ArgumentNullException(nameof(dotnetDumpService));
241 ArgumentNullException.ThrowIfNull(metricFactory);
242 this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
243 this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
244 this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration));
245 this.instance = instance ?? throw new ArgumentNullException(nameof(instance));
246
247 sessionsLaunched = metricFactory.CreateCounter("tgs_sessions_launched", "The number of game server processes created");
248 lastSessionLaunch = metricFactory.CreateGauge("tgs_session_start_time", "The UTC unix timestamp the most recent session was started");
249 }
250
252 #pragma warning disable CA1506 // TODO: Decomplexify
253 public async ValueTask<ISessionController> LaunchNew(
254 IDmbProvider dmbProvider,
255 IEngineExecutableLock? currentByondLock,
256 DreamDaemonLaunchParameters launchParameters,
257 bool apiValidate,
258 CancellationToken cancellationToken)
259 {
260 logger.LogTrace("Begin session launch...");
261 if (!launchParameters.Port.HasValue)
262 throw new InvalidOperationException("Given port is null!");
263
264 switch (dmbProvider.CompileJob.MinimumSecurityLevel)
265 {
266 case DreamDaemonSecurity.Ultrasafe:
267 break;
268 case DreamDaemonSecurity.Safe:
269 if (launchParameters.SecurityLevel == DreamDaemonSecurity.Ultrasafe)
270 {
271 logger.LogTrace("Boosting security level to minimum of Safe");
272 launchParameters.SecurityLevel = DreamDaemonSecurity.Safe;
273 }
274
275 break;
276 case DreamDaemonSecurity.Trusted:
277 if (launchParameters.SecurityLevel != DreamDaemonSecurity.Trusted)
278 logger.LogTrace("Boosting security level to minimum of Trusted");
279
280 launchParameters.SecurityLevel = DreamDaemonSecurity.Trusted;
281 break;
282 default:
283 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid DreamDaemonSecurity value: {0}", dmbProvider.CompileJob.MinimumSecurityLevel));
284 }
285
286 // get the byond lock
287 var engineLock = currentByondLock ?? await engineManager.UseExecutables(
288 dmbProvider.EngineVersion,
289 gameIOManager.ConcatPath(dmbProvider.Directory, dmbProvider.DmbName),
290 cancellationToken);
291 try
292 {
293 logger.LogDebug(
294 "Launching session with CompileJob {compileJobId}...",
295 dmbProvider.CompileJob.Id);
296
297 // mad this isn't abstracted but whatever
298 var engineType = dmbProvider.EngineVersion.Engine!.Value;
299 if (engineType == EngineType.Byond)
301
302 await PortBindTest(launchParameters.Port.Value, engineType, cancellationToken);
303
304 string? outputFilePath = null;
305 var preserveLogFile = true;
306
307 var hasStandardOutput = engineLock.HasStandardOutput;
308 if (launchParameters.LogOutput!.Value)
309 {
310 var now = DateTimeOffset.UtcNow;
311 var dateDirectory = diagnosticsIOManager.ConcatPath(DreamDaemonLogsPath, now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
312 await diagnosticsIOManager.CreateDirectory(dateDirectory, cancellationToken);
313 outputFilePath = diagnosticsIOManager.ResolvePath(
315 dateDirectory,
316 $"server-utc-{now.ToString("yyyy-MM-dd-HH-mm-ss", CultureInfo.InvariantCulture)}{(apiValidate ? "-dmapi" : String.Empty)}.log"));
317
318 logger.LogInformation("Logging server output to {path}...", outputFilePath);
319 }
320 else if (!hasStandardOutput)
321 {
322 outputFilePath = gameIOManager.ConcatPath(dmbProvider.Directory, $"{Guid.NewGuid()}.server.log");
323 preserveLogFile = false;
324 }
325
326 var accessIdentifier = cryptographySuite.GetSecureString();
327
328 if (!apiValidate && dmbProvider.CompileJob.DMApiVersion == null)
329 logger.LogDebug("Session will have no DMAPI support!");
330
331 // launch dd
332 var process = await CreateGameServerProcess(
333 dmbProvider,
334 engineLock,
335 launchParameters,
336 accessIdentifier,
337 outputFilePath,
338 apiValidate,
339 cancellationToken);
340
341 try
342 {
343 var chatTrackingContext = chat.CreateTrackingContext();
344
345 try
346 {
347 var runtimeInformation = CreateRuntimeInformation(
348 dmbProvider,
349 chatTrackingContext,
350 launchParameters.SecurityLevel!.Value,
351 launchParameters.Visibility!.Value,
352 apiValidate);
353
354 var reattachInformation = new ReattachInformation(
355 dmbProvider,
356 process,
357 runtimeInformation,
358 accessIdentifier,
359 launchParameters.Port.Value);
360
361 var byondTopicSender = topicClientFactory.CreateTopicClient(
362 TimeSpan.FromMilliseconds(
363 launchParameters.TopicRequestTimeout!.Value));
364
365 var sessionController = new SessionController(
366 reattachInformation,
367 instance,
368 process,
369 engineLock,
370 byondTopicSender,
371 chatTrackingContext,
373 chat,
378 loggerFactory.CreateLogger<SessionController>(),
379 () => LogDDOutput(
380 process,
381 outputFilePath,
382 hasStandardOutput,
383 preserveLogFile,
384 CancellationToken.None), // DCT: None available
385 launchParameters.StartupTimeout,
386 false,
387 apiValidate);
388
389 if (!apiValidate)
390 {
391 sessionsLaunched.Inc();
392 lastSessionLaunch.SetToCurrentTimeUtc();
393 }
394
395 return sessionController;
396 }
397 catch
398 {
399 chatTrackingContext.Dispose();
400 throw;
401 }
402 }
403 catch
404 {
405 await using (process)
406 {
407 process.Terminate();
408 await process.Lifetime;
409 throw;
410 }
411 }
412 }
413 catch
414 {
415 if (currentByondLock == null)
416 engineLock.Dispose();
417 throw;
418 }
419 }
420#pragma warning restore CA1506
421
423 public async ValueTask<ISessionController?> Reattach(
424 ReattachInformation reattachInformation,
425 CancellationToken cancellationToken)
426 {
427 ArgumentNullException.ThrowIfNull(reattachInformation);
428
429 logger.LogTrace("Begin session reattach...");
430 var byondTopicSender = topicClientFactory.CreateTopicClient(reattachInformation.TopicRequestTimeout);
431 var engineLock = await engineManager.UseExecutables(
432 reattachInformation.Dmb.EngineVersion,
433 null, // Doesn't matter if it's trusted or not on reattach
434 cancellationToken);
435
436 try
437 {
438 logger.LogDebug(
439 "Attaching to session PID: {pid}, CompileJob: {compileJobId}...",
440 reattachInformation.ProcessId,
441 reattachInformation.Dmb.CompileJob.Id);
442
443 var process = processExecutor.GetProcess(reattachInformation.ProcessId);
444 if (process == null)
445 return null;
446
447 try
448 {
449 if (engineLock.PromptsForNetworkAccess)
451
452 var chatTrackingContext = chat.CreateTrackingContext();
453 try
454 {
455 var runtimeInformation = CreateRuntimeInformation(
456 reattachInformation.Dmb,
457 chatTrackingContext,
458 reattachInformation.LaunchSecurityLevel,
459 reattachInformation.LaunchVisibility,
460 false);
461 reattachInformation.SetRuntimeInformation(runtimeInformation);
462
463 var controller = new SessionController(
464 reattachInformation,
465 instance,
466 process,
467 engineLock,
468 byondTopicSender,
469 chatTrackingContext,
471 chat,
476 loggerFactory.CreateLogger<SessionController>(),
477 () => ValueTask.CompletedTask,
478 null,
479 true,
480 false);
481
482 process = null;
483 engineLock = null;
484 chatTrackingContext = null;
485
486 return controller;
487 }
488 catch
489 {
490 chatTrackingContext?.Dispose();
491 throw;
492 }
493 }
494 catch
495 {
496 if (process != null)
497 await process.DisposeAsync();
498
499 throw;
500 }
501 }
502 catch
503 {
504 engineLock?.Dispose();
505 throw;
506 }
507 }
508
520 async ValueTask<IProcess> CreateGameServerProcess(
521 IDmbProvider dmbProvider,
522 IEngineExecutableLock engineLock,
523 DreamDaemonLaunchParameters launchParameters,
524 string accessIdentifier,
525 string? logFilePath,
526 bool apiValidate,
527 CancellationToken cancellationToken)
528 {
529 // important to run on all ports to allow port changing
530 var environment = await engineLock.LoadEnv(logger, false, cancellationToken);
531 var arguments = engineLock.FormatServerArguments(
532 dmbProvider,
533 new Dictionary<string, string>
534 {
536 { DMApiConstants.ParamServerPort, serverPortProvider.HttpApiPort.ToString(CultureInfo.InvariantCulture) },
537 { DMApiConstants.ParamAccessIdentifier, accessIdentifier },
538 },
539 launchParameters,
540 !engineLock.HasStandardOutput || engineLock.PreferFileLogging
541 ? logFilePath
542 : null);
543
544 // If this isnt a staging DD (From a Deployment), fire off events
545 if (!apiValidate)
547 EventType.DreamDaemonPreLaunch,
548 Enumerable.Empty<string?>(),
549 false,
550 cancellationToken);
551
552 var process = await processExecutor.LaunchProcess(
553 engineLock.ServerExePath,
554 dmbProvider.Directory,
555 arguments,
556 cancellationToken,
557 environment,
558 logFilePath,
559 engineLock.HasStandardOutput,
560 true);
561
562 try
563 {
564 if (!apiValidate)
565 {
567 process.AdjustPriority(true);
568 }
570 process.AdjustPriority(false);
571
572 if (!engineLock.HasStandardOutput)
574
575 if (!apiValidate)
577 EventType.DreamDaemonLaunch,
578 new List<string>
579 {
580 process.Id.ToString(CultureInfo.InvariantCulture),
581 },
582 false,
583 cancellationToken);
584
585 return process;
586 }
587 catch
588 {
589 await using (process)
590 {
591 process.Terminate();
592 await process.Lifetime;
593 throw;
594 }
595 }
596 }
597
607 async ValueTask LogDDOutput(IProcess process, string? outputFilePath, bool cliSupported, bool preserveFile, CancellationToken cancellationToken)
608 {
609 try
610 {
611 string? ddOutput = null;
612 if (cliSupported)
613 ddOutput = (await process.GetCombinedOutput(cancellationToken))!;
614
615 if (ddOutput == null)
616 try
617 {
618 var dreamDaemonLogBytes = await gameIOManager.ReadAllBytes(
619 outputFilePath!,
620 cancellationToken);
621
622 ddOutput = Encoding.UTF8.GetString(dreamDaemonLogBytes);
623 }
624 finally
625 {
626 if (!preserveFile)
627 try
628 {
629 logger.LogTrace("Deleting temporary log file {path}...", outputFilePath);
630 await gameIOManager.DeleteFile(outputFilePath!, cancellationToken);
631 }
632 catch (Exception ex)
633 {
634 // this is expected on OD at time of the support changes.
635 // I've open a change to fix it: https://github.com/space-wizards/RobustToolbox/pull/4501
636 logger.LogWarning(ex, "Failed to delete server log file {outputFilePath}!", outputFilePath);
637 }
638 }
639
640 logger.LogTrace(
641 "Server Output:{newLine}{output}",
642 Environment.NewLine,
643 ddOutput);
644 }
645 catch (Exception ex)
646 {
647 logger.LogWarning(ex, "Error reading server output!");
648 }
649 }
650
661 IDmbProvider dmbProvider,
662 IChatTrackingContext chatTrackingContext,
663 DreamDaemonSecurity securityLevel,
664 DreamDaemonVisibility visibility,
665 bool apiValidateOnly)
666 => new(
667 chatTrackingContext,
668 dmbProvider,
670 instance.Name!,
671 securityLevel,
672 visibility,
674 apiValidateOnly);
675
680 async ValueTask CheckPagerIsNotRunning()
681 {
683 return;
684
685 await using var otherProcess = processExecutor.GetProcessByName("byond");
686 if (otherProcess == null)
687 return;
688
689 var otherUsername = otherProcess.GetExecutingUsername();
690
691 await using var ourProcess = processExecutor.GetCurrentProcess();
692 var ourUsername = ourProcess.GetExecutingUsername();
693
694 if (otherUsername.Equals(ourUsername, StringComparison.Ordinal))
695 throw new JobException(ErrorCode.DreamDaemonPagerRunning);
696 }
697 }
698}
virtual ? long Id
The ID of the entity.
Definition EntityId.cs:14
Metadata about a server instance.
Definition Instance.cs:9
virtual ? Version DMApiVersion
The DMAPI Version.
Definition CompileJob.cs:43
DreamDaemonSecurity? MinimumSecurityLevel
The minimum DreamDaemonSecurity required to run the CompileJob's output.
Definition CompileJob.cs:35
ushort? Port
The port DreamDaemon uses. This should be publically accessible.
DreamDaemonVisibility? Visibility
The DreamDaemonVisibility level of DreamDaemon. No-op for EngineType.OpenDream.
bool? LogOutput
If process output/error text should be logged.
uint? TopicRequestTimeout
The timeout for sending and receiving BYOND topics in milliseconds.
DreamDaemonSecurity? SecurityLevel
The DreamDaemonSecurity level of DreamDaemon. No-op for EngineType.OpenDream.
Representation of the initial data passed as part of a BridgeCommandType.Startup request.
Constants used for communication with the DMAPI.
const string ParamServerPort
Identifies the Core.IServerPortProvider.HttpApiPort of the server.
const string ParamAccessIdentifier
Identifies the DMApiParameters.AccessIdentifier for the session.
const string ParamApiVersion
Identifies a DMAPI execution with the version as the value.
static readonly Version InteropVersion
The DMAPI InteropVersion being used.
Parameters necessary for duplicating a ISessionController session.
TimeSpan TopicRequestTimeout
The TimeSpan which indicates when topic requests should timeout.
void SetRuntimeInformation(RuntimeInformation runtimeInformation)
Set the RuntimeInformation post construction.
IDmbProvider Dmb
The IDmbProvider used by DreamDaemon.
readonly IEventConsumer eventConsumer
The IEventConsumer for the SessionControllerFactory.
readonly ITopicClientFactory topicClientFactory
The ITopicClientFactory for the SessionControllerFactory.
readonly SessionConfiguration sessionConfiguration
The SessionConfiguration for the SessionControllerFactory.
readonly IServerPortProvider serverPortProvider
The IServerPortProvider for the SessionControllerFactory.
readonly ILoggerFactory loggerFactory
The ILoggerFactory for the SessionControllerFactory.
readonly IProcessExecutor processExecutor
The IProcessExecutor for the SessionControllerFactory.
readonly IIOManager gameIOManager
The IIOManager for the Game directory.
async ValueTask CheckPagerIsNotRunning()
Make sure the BYOND pager is not running.
readonly IPlatformIdentifier platformIdentifier
The IPlatformIdentifier for the SessionControllerFactory.
async ValueTask LogDDOutput(IProcess process, string? outputFilePath, bool cliSupported, bool preserveFile, CancellationToken cancellationToken)
Attempts to log DreamDaemon output.
RuntimeInformation CreateRuntimeInformation(IDmbProvider dmbProvider, IChatTrackingContext chatTrackingContext, DreamDaemonSecurity securityLevel, DreamDaemonVisibility visibility, bool apiValidateOnly)
Create RuntimeInformation.
readonly ICryptographySuite cryptographySuite
The ICryptographySuite for the SessionControllerFactory.
async ValueTask< IProcess > CreateGameServerProcess(IDmbProvider dmbProvider, IEngineExecutableLock engineLock, DreamDaemonLaunchParameters launchParameters, string accessIdentifier, string? logFilePath, bool apiValidate, CancellationToken cancellationToken)
Creates the game server IProcess.
readonly IBridgeRegistrar bridgeRegistrar
The IBridgeRegistrar for the SessionControllerFactory.
async ValueTask PortBindTest(ushort port, EngineType engineType, CancellationToken cancellationToken)
Check if a given port can be bound to.
const string DreamDaemonLogsPath
Path in Diagnostics folder to DreamDaemon logs.
readonly Counter sessionsLaunched
The number of sessions launched.
readonly Api.Models.Instance instance
The Api.Models.Instance for the SessionControllerFactory.
readonly INetworkPromptReaper networkPromptReaper
The INetworkPromptReaper for the SessionControllerFactory.
readonly ILogger< SessionControllerFactory > logger
The ILogger for the SessionControllerFactory.
readonly IChatManager chat
The IChatManager for the SessionControllerFactory.
readonly IAssemblyInformationProvider assemblyInformationProvider
The IAssemblyInformationProvider for the SessionControllerFactory.
async ValueTask< ISessionController > LaunchNew(IDmbProvider dmbProvider, IEngineExecutableLock? currentByondLock, DreamDaemonLaunchParameters launchParameters, bool apiValidate, CancellationToken cancellationToken)
Create a ISessionController from a freshly launch DreamDaemon instance.A ValueTask<TResult> resulting...
SessionControllerFactory(IProcessExecutor processExecutor, IEngineManager engineManager, ITopicClientFactory topicClientFactory, ICryptographySuite cryptographySuite, IAssemblyInformationProvider assemblyInformationProvider, IIOManager gameIOManager, IIOManager diagnosticsIOManager, IChatManager chat, INetworkPromptReaper networkPromptReaper, IPlatformIdentifier platformIdentifier, IBridgeRegistrar bridgeRegistrar, IServerPortProvider serverPortProvider, IEventConsumer eventConsumer, IAsyncDelayer asyncDelayer, IDotnetDumpService dotnetDumpService, IMetricFactory metricFactory, ILoggerFactory loggerFactory, ILogger< SessionControllerFactory > logger, SessionConfiguration sessionConfiguration, Api.Models.Instance instance)
Initializes a new instance of the SessionControllerFactory class.
readonly IDotnetDumpService dotnetDumpService
The IDotnetDumpService for the SessionControllerFactory.
readonly IEngineManager engineManager
The IEngineManager for the SessionControllerFactory.
async ValueTask< ISessionController?> Reattach(ReattachInformation reattachInformation, CancellationToken cancellationToken)
Create a ISessionController from an existing DreamDaemon instance.A ValueTask<TResult> resulting in a...
readonly Gauge lastSessionLaunch
The time the current session was launched.
readonly IAsyncDelayer asyncDelayer
The IAsyncDelayer for the SessionControllerFactory.
readonly IIOManager diagnosticsIOManager
The IIOManager for the Diagnostics directory.
Configuration options for the game sessions.
bool HighPriorityLiveDreamDaemon
If the public DreamDaemon instances are set to be above normal priority processes.
bool LowPriorityDeploymentProcesses
If the deployment DreamMaker and DreamDaemon instances are set to be below normal priority processes.
Extension methods for the Socket class.
static void BindTest(IPlatformIdentifier platformIdentifier, ushort port, bool includeIPv6, bool udp)
Attempt to exclusively bind to a given port .
Operation exceptions thrown from the context of a Models.Job.
DreamDaemonSecurity LaunchSecurityLevel
The DreamDaemonSecurity level DreamDaemon was launched with.
DreamDaemonVisibility LaunchVisibility
The DreamDaemonVisibility DreamDaemon was launched with.
For managing connected chat services.
IChatTrackingContext CreateTrackingContext()
Start tracking Commands.CustomCommands and ChannelRepresentations.
Represents a tracking of dynamic chat json files.
Provides absolute paths to the latest compiled .dmbs.
EngineVersion EngineVersion
The Api.Models.EngineVersion used to build the .dmb.
Models.CompileJob CompileJob
The CompileJob of the .dmb.
Represents usage of the two primary BYOND server executables.
string ServerExePath
The full path to the game server executable.
ValueTask< Dictionary< string, string >?> LoadEnv(ILogger logger, bool forCompiler, CancellationToken cancellationToken)
Loads the environment settings for either the server or compiler.
string FormatServerArguments(IDmbProvider dmbProvider, IReadOnlyDictionary< string, string > parameters, DreamDaemonLaunchParameters launchParameters, string? logFilePath)
Return the command line arguments for launching with given launchParameters .
bool HasStandardOutput
If ServerExePath supports being run as a command-line application and outputs log information to be c...
ValueTask< IEngineExecutableLock > UseExecutables(EngineVersion? requiredVersion, string? trustDmbFullPath, CancellationToken cancellationToken)
Lock the current installation's location and return a IEngineExecutableLock.
Consumes EventTypes and takes the appropriate actions.
ValueTask HandleEvent(EventType eventType, IEnumerable< string?> parameters, bool deploymentPipeline, CancellationToken cancellationToken)
Handle a given eventType .
ITopicClient CreateTopicClient(TimeSpan timeout)
Create a ITopicClient.
Provides access to the server's HttpApiPort.
ushort HttpApiPort
The port the server listens on.
Interface for using filesystems.
Definition IIOManager.cs:13
string ResolvePath()
Retrieve the full path of the current working directory.
ValueTask< byte[]> ReadAllBytes(string path, CancellationToken cancellationToken)
Returns all the contents of a file at path as a byte array.
string ConcatPath(params string[] paths)
Combines an array of strings into a path.
Task CreateDirectory(string path, CancellationToken cancellationToken)
Create a directory at path .
Task DeleteFile(string path, CancellationToken cancellationToken)
Deletes a file at path .
Contains various cryptographic functions.
string GetSecureString()
Generates a 40-length secure ascii string.
Service for managing the dotnet-dump installation.
On Windows, DreamDaemon will show an unskippable prompt when using /world/proc/OpenPort()....
void RegisterProcess(IProcess process)
Register a given process for network prompt reaping.
For identifying the current platform.
bool IsWindows
If the current platform is a Windows platform.
ValueTask< IProcess > LaunchProcess(string fileName, string workingDirectory, string arguments, CancellationToken cancellationToken, IReadOnlyDictionary< string, string >? environment=null, string? fileRedirect=null, bool readStandardHandles=false, bool noShellExecute=false)
Launch a IProcess.
IProcess GetCurrentProcess()
Get a IProcess representing the running executable.
IProcess? GetProcess(int id)
Get a IProcess by id .
IProcess? GetProcessByName(string name)
Get a IProcess with a given name .
Abstraction over a global::System.Diagnostics.Process.
Definition IProcess.cs:11
string GetExecutingUsername()
Get the name of the account executing the IProcess.
Task< string?> GetCombinedOutput(CancellationToken cancellationToken)
Get the stderr and stdout output of the IProcess.
ValueTask Delay(TimeSpan timeSpan, CancellationToken cancellationToken)
Create a Task that completes after a given timeSpan .
ErrorCode
Types of Response.ErrorMessageResponses that the API may return.
Definition ErrorCode.cs:12
DreamDaemonVisibility
The visibility setting for DreamDaemon.
DreamDaemonSecurity
DreamDaemon's security level.
EngineType
The type of engine the codebase is using.
Definition EngineType.cs:7
EventType
Types of events. Mirror in tgs.dm. Prefer last listed name for script.
Definition EventType.cs:7