tgstation-server 6.12.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.Net.Sockets;
5using System.Text;
6using System.Threading;
7using System.Threading.Tasks;
8
9using Microsoft.Extensions.Logging;
10
28
30{
33 {
37 const string DreamDaemonLogsPath = "DreamDaemonLogs";
38
43
48
53
58
63
68
73
78
83
88
93
98
103
108
113
117 readonly ILoggerFactory loggerFactory;
118
122 readonly ILogger<SessionControllerFactory> logger;
123
128
133
141 async ValueTask PortBindTest(ushort port, EngineType engineType, CancellationToken cancellationToken)
142 {
143 logger.LogTrace("Bind test: {port}", port);
144 try
145 {
146 // GIVE ME THE FUCKING PORT BACK WINDOWS!!!!
147 const int MaxAttempts = 5;
148 for (var i = 0; i < MaxAttempts; ++i)
149 try
150 {
151 SocketExtensions.BindTest(platformIdentifier, port, false, engineType == EngineType.OpenDream);
152 if (i > 0)
153 logger.LogDebug("Clearing the socket took {iterations} attempts :/", i + 1);
154
155 break;
156 }
157 catch (SocketException ex) when (platformIdentifier.IsWindows && ex.SocketErrorCode == SocketError.AddressAlreadyInUse && i < (MaxAttempts - 1))
158 {
159 await asyncDelayer.Delay(TimeSpan.FromSeconds(1), cancellationToken);
160 }
161 }
162 catch (SocketException ex) when (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
163 {
164 throw new JobException(ErrorCode.GameServerPortInUse, ex);
165 }
166 }
167
206 ILoggerFactory loggerFactory,
207 ILogger<SessionControllerFactory> logger,
209 Api.Models.Instance instance)
210 {
211 this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
212 this.engineManager = engineManager ?? throw new ArgumentNullException(nameof(engineManager));
213 this.topicClientFactory = topicClientFactory ?? throw new ArgumentNullException(nameof(topicClientFactory));
214 this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite));
215 this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
216 this.gameIOManager = gameIOManager ?? throw new ArgumentNullException(nameof(gameIOManager));
217 this.diagnosticsIOManager = diagnosticsIOManager ?? throw new ArgumentNullException(nameof(diagnosticsIOManager));
218 this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
219 this.networkPromptReaper = networkPromptReaper ?? throw new ArgumentNullException(nameof(networkPromptReaper));
220 this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier));
221 this.bridgeRegistrar = bridgeRegistrar ?? throw new ArgumentNullException(nameof(bridgeRegistrar));
222 this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider));
223 this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
224 this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
225 this.dotnetDumpService = dotnetDumpService ?? throw new ArgumentNullException(nameof(dotnetDumpService));
226 this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
227 this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
228 this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration));
229 this.instance = instance ?? throw new ArgumentNullException(nameof(instance));
230 }
231
233 #pragma warning disable CA1506 // TODO: Decomplexify
234 public async ValueTask<ISessionController> LaunchNew(
235 IDmbProvider dmbProvider,
236 IEngineExecutableLock? currentByondLock,
237 DreamDaemonLaunchParameters launchParameters,
238 bool apiValidate,
239 CancellationToken cancellationToken)
240 {
241 logger.LogTrace("Begin session launch...");
242 if (!launchParameters.Port.HasValue)
243 throw new InvalidOperationException("Given port is null!");
244
245 switch (dmbProvider.CompileJob.MinimumSecurityLevel)
246 {
247 case DreamDaemonSecurity.Ultrasafe:
248 break;
249 case DreamDaemonSecurity.Safe:
250 if (launchParameters.SecurityLevel == DreamDaemonSecurity.Ultrasafe)
251 {
252 logger.LogTrace("Boosting security level to minimum of Safe");
253 launchParameters.SecurityLevel = DreamDaemonSecurity.Safe;
254 }
255
256 break;
257 case DreamDaemonSecurity.Trusted:
258 if (launchParameters.SecurityLevel != DreamDaemonSecurity.Trusted)
259 logger.LogTrace("Boosting security level to minimum of Trusted");
260
261 launchParameters.SecurityLevel = DreamDaemonSecurity.Trusted;
262 break;
263 default:
264 throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid DreamDaemonSecurity value: {0}", dmbProvider.CompileJob.MinimumSecurityLevel));
265 }
266
267 // get the byond lock
268 var engineLock = currentByondLock ?? await engineManager.UseExecutables(
269 dmbProvider.EngineVersion,
270 gameIOManager.ConcatPath(dmbProvider.Directory, dmbProvider.DmbName),
271 cancellationToken);
272 try
273 {
274 logger.LogDebug(
275 "Launching session with CompileJob {compileJobId}...",
276 dmbProvider.CompileJob.Id);
277
278 // mad this isn't abstracted but whatever
279 var engineType = dmbProvider.EngineVersion.Engine!.Value;
280 if (engineType == EngineType.Byond)
282
283 await PortBindTest(launchParameters.Port.Value, engineType, cancellationToken);
284
285 string? outputFilePath = null;
286 var preserveLogFile = true;
287
288 var hasStandardOutput = engineLock.HasStandardOutput;
289 if (launchParameters.LogOutput!.Value)
290 {
291 var now = DateTimeOffset.UtcNow;
292 var dateDirectory = diagnosticsIOManager.ConcatPath(DreamDaemonLogsPath, now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
293 await diagnosticsIOManager.CreateDirectory(dateDirectory, cancellationToken);
294 outputFilePath = diagnosticsIOManager.ResolvePath(
296 dateDirectory,
297 $"server-utc-{now.ToString("yyyy-MM-dd-HH-mm-ss", CultureInfo.InvariantCulture)}{(apiValidate ? "-dmapi" : String.Empty)}.log"));
298
299 logger.LogInformation("Logging server output to {path}...", outputFilePath);
300 }
301 else if (!hasStandardOutput)
302 {
303 outputFilePath = gameIOManager.ConcatPath(dmbProvider.Directory, $"{Guid.NewGuid()}.server.log");
304 preserveLogFile = false;
305 }
306
307 var accessIdentifier = cryptographySuite.GetSecureString();
308
309 if (!apiValidate && dmbProvider.CompileJob.DMApiVersion == null)
310 logger.LogDebug("Session will have no DMAPI support!");
311
312 // launch dd
313 var process = await CreateGameServerProcess(
314 dmbProvider,
315 engineLock,
316 launchParameters,
317 accessIdentifier,
318 outputFilePath,
319 apiValidate,
320 cancellationToken);
321
322 try
323 {
324 var chatTrackingContext = chat.CreateTrackingContext();
325
326 try
327 {
328 var runtimeInformation = CreateRuntimeInformation(
329 dmbProvider,
330 chatTrackingContext,
331 launchParameters.SecurityLevel!.Value,
332 launchParameters.Visibility!.Value,
333 apiValidate);
334
335 var reattachInformation = new ReattachInformation(
336 dmbProvider,
337 process,
338 runtimeInformation,
339 accessIdentifier,
340 launchParameters.Port.Value);
341
342 var byondTopicSender = topicClientFactory.CreateTopicClient(
343 TimeSpan.FromMilliseconds(
344 launchParameters.TopicRequestTimeout!.Value));
345
346 var sessionController = new SessionController(
347 reattachInformation,
348 instance,
349 process,
350 engineLock,
351 byondTopicSender,
352 chatTrackingContext,
354 chat,
359 loggerFactory.CreateLogger<SessionController>(),
360 () => LogDDOutput(
361 process,
362 outputFilePath,
363 hasStandardOutput,
364 preserveLogFile,
365 CancellationToken.None), // DCT: None available
366 launchParameters.StartupTimeout,
367 false,
368 apiValidate);
369
370 return sessionController;
371 }
372 catch
373 {
374 chatTrackingContext.Dispose();
375 throw;
376 }
377 }
378 catch
379 {
380 await using (process)
381 {
382 process.Terminate();
383 await process.Lifetime;
384 throw;
385 }
386 }
387 }
388 catch
389 {
390 if (currentByondLock == null)
391 engineLock.Dispose();
392 throw;
393 }
394 }
395#pragma warning restore CA1506
396
398 public async ValueTask<ISessionController?> Reattach(
399 ReattachInformation reattachInformation,
400 CancellationToken cancellationToken)
401 {
402 ArgumentNullException.ThrowIfNull(reattachInformation);
403
404 logger.LogTrace("Begin session reattach...");
405 var byondTopicSender = topicClientFactory.CreateTopicClient(reattachInformation.TopicRequestTimeout);
406 var engineLock = await engineManager.UseExecutables(
407 reattachInformation.Dmb.EngineVersion,
408 null, // Doesn't matter if it's trusted or not on reattach
409 cancellationToken);
410
411 try
412 {
413 logger.LogDebug(
414 "Attaching to session PID: {pid}, CompileJob: {compileJobId}...",
415 reattachInformation.ProcessId,
416 reattachInformation.Dmb.CompileJob.Id);
417
418 var process = processExecutor.GetProcess(reattachInformation.ProcessId);
419 if (process == null)
420 return null;
421
422 try
423 {
424 if (engineLock.PromptsForNetworkAccess)
426
427 var chatTrackingContext = chat.CreateTrackingContext();
428 try
429 {
430 var runtimeInformation = CreateRuntimeInformation(
431 reattachInformation.Dmb,
432 chatTrackingContext,
433 reattachInformation.LaunchSecurityLevel,
434 reattachInformation.LaunchVisibility,
435 false);
436 reattachInformation.SetRuntimeInformation(runtimeInformation);
437
438 var controller = new SessionController(
439 reattachInformation,
440 instance,
441 process,
442 engineLock,
443 byondTopicSender,
444 chatTrackingContext,
446 chat,
451 loggerFactory.CreateLogger<SessionController>(),
452 () => ValueTask.CompletedTask,
453 null,
454 true,
455 false);
456
457 process = null;
458 engineLock = null;
459 chatTrackingContext = null;
460
461 return controller;
462 }
463 catch
464 {
465 chatTrackingContext?.Dispose();
466 throw;
467 }
468 }
469 catch
470 {
471 if (process != null)
472 await process.DisposeAsync();
473
474 throw;
475 }
476 }
477 catch
478 {
479 engineLock?.Dispose();
480 throw;
481 }
482 }
483
495 async ValueTask<IProcess> CreateGameServerProcess(
496 IDmbProvider dmbProvider,
497 IEngineExecutableLock engineLock,
498 DreamDaemonLaunchParameters launchParameters,
499 string accessIdentifier,
500 string? logFilePath,
501 bool apiValidate,
502 CancellationToken cancellationToken)
503 {
504 // important to run on all ports to allow port changing
505 var environment = await engineLock.LoadEnv(logger, false, cancellationToken);
506 var arguments = engineLock.FormatServerArguments(
507 dmbProvider,
508 new Dictionary<string, string>
509 {
511 { DMApiConstants.ParamServerPort, serverPortProvider.HttpApiPort.ToString(CultureInfo.InvariantCulture) },
512 { DMApiConstants.ParamAccessIdentifier, accessIdentifier },
513 },
514 launchParameters,
515 !engineLock.HasStandardOutput || engineLock.PreferFileLogging
516 ? logFilePath
517 : null);
518
519 var process = await processExecutor.LaunchProcess(
520 engineLock.ServerExePath,
521 dmbProvider.Directory,
522 arguments,
523 cancellationToken,
524 environment,
525 logFilePath,
526 engineLock.HasStandardOutput,
527 true);
528
529 try
530 {
531 if (!apiValidate)
532 {
534 process.AdjustPriority(true);
535 }
537 process.AdjustPriority(false);
538
539 if (!engineLock.HasStandardOutput)
541
542 // If this isnt a staging DD (From a Deployment), fire off an event
543 if (!apiValidate)
545 EventType.DreamDaemonLaunch,
546 new List<string>
547 {
548 process.Id.ToString(CultureInfo.InvariantCulture),
549 },
550 false,
551 cancellationToken);
552
553 return process;
554 }
555 catch
556 {
557 await using (process)
558 {
559 process.Terminate();
560 await process.Lifetime;
561 throw;
562 }
563 }
564 }
565
575 async ValueTask LogDDOutput(IProcess process, string? outputFilePath, bool cliSupported, bool preserveFile, CancellationToken cancellationToken)
576 {
577 try
578 {
579 string? ddOutput = null;
580 if (cliSupported)
581 ddOutput = (await process.GetCombinedOutput(cancellationToken))!;
582
583 if (ddOutput == null)
584 try
585 {
586 var dreamDaemonLogBytes = await gameIOManager.ReadAllBytes(
587 outputFilePath!,
588 cancellationToken);
589
590 ddOutput = Encoding.UTF8.GetString(dreamDaemonLogBytes);
591 }
592 finally
593 {
594 if (!preserveFile)
595 try
596 {
597 logger.LogTrace("Deleting temporary log file {path}...", outputFilePath);
598 await gameIOManager.DeleteFile(outputFilePath!, cancellationToken);
599 }
600 catch (Exception ex)
601 {
602 // this is expected on OD at time of the support changes.
603 // I've open a change to fix it: https://github.com/space-wizards/RobustToolbox/pull/4501
604 logger.LogWarning(ex, "Failed to delete server log file {outputFilePath}!", outputFilePath);
605 }
606 }
607
608 logger.LogTrace(
609 "Server Output:{newLine}{output}",
610 Environment.NewLine,
611 ddOutput);
612 }
613 catch (Exception ex)
614 {
615 logger.LogWarning(ex, "Error reading server output!");
616 }
617 }
618
629 IDmbProvider dmbProvider,
630 IChatTrackingContext chatTrackingContext,
631 DreamDaemonSecurity securityLevel,
632 DreamDaemonVisibility visibility,
633 bool apiValidateOnly)
634 => new(
635 chatTrackingContext,
636 dmbProvider,
638 instance.Name!,
639 securityLevel,
640 visibility,
642 apiValidateOnly);
643
648 async ValueTask CheckPagerIsNotRunning()
649 {
651 return;
652
653 await using var otherProcess = processExecutor.GetProcessByName("byond");
654 if (otherProcess == null)
655 return;
656
657 var otherUsername = otherProcess.GetExecutingUsername();
658
659 await using var ourProcess = processExecutor.GetCurrentProcess();
660 var ourUsername = ourProcess.GetExecutingUsername();
661
662 if (otherUsername.Equals(ourUsername, StringComparison.Ordinal))
663 throw new JobException(ErrorCode.DreamDaemonPagerRunning);
664 }
665 }
666}
virtual ? long Id
The ID of the entity.
Definition EntityId.cs:13
Metadata about a server instance.
Definition Instance.cs:9
virtual ? Version DMApiVersion
The DMAPI Version.
Definition CompileJob.cs:41
DreamDaemonSecurity? MinimumSecurityLevel
The minimum DreamDaemonSecurity required to run the CompileJob's output.
Definition CompileJob.cs:34
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.
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, ILoggerFactory loggerFactory, ILogger< SessionControllerFactory > logger, SessionConfiguration sessionConfiguration, Api.Models.Instance instance)
Initializes a new instance of the SessionControllerFactory class.
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 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...
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 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