2using System.Collections.Generic;
3using System.Globalization;
7using System.Threading.Tasks;
9using Microsoft.Extensions.Logging;
10using Microsoft.Extensions.Logging.Abstractions;
39 internal static bool LogTopicRequests {
get;
set; } =
true;
50 throw new InvalidOperationException(
"ApiValidated cannot be checked while Lifetime is incomplete!");
91 var tcs =
new TaskCompletionSource<Task>();
94 var toAwait = await tcs.Task;
99 tcs.SetResult(Interlocked.Exchange(ref
rebootGate, Wrap()));
291 ILogger<SessionController> logger,
292 Func<ValueTask> postLifetimeCallback,
293 uint? startupTimeout,
298 ReattachInformation = reattachInformation ??
throw new ArgumentNullException(nameof(reattachInformation));
299 this.metadata =
metadata ??
throw new ArgumentNullException(nameof(
metadata));
300 this.process =
process ??
throw new ArgumentNullException(nameof(
process));
304 ArgumentNullException.ThrowIfNull(bridgeRegistrar);
306 this.chat =
chat ??
throw new ArgumentNullException(nameof(
chat));
307 ArgumentNullException.ThrowIfNull(assemblyInformationProvider);
321 primeTcs =
new TaskCompletionSource();
347 "Not registering session with {reasonWhyDmApiIsBad} DMAPI version for interop!",
350 : $
"incompatible ({reattachInformation.Dmb.CompileJob.DMApiVersion})");
352 async Task<int?> WrapLifetime()
355 await postLifetimeCallback();
365 assemblyInformationProvider,
372 "Created session controller. CommsKey: {accessIdentifier}, Port: {port}",
374 reattachInformation.
Port);
387 Logger.LogTrace(
"Disposing...");
390 var cancellationToken = CancellationToken.None;
408 if (initialDmb !=
null)
409 await initialDmb.DisposeAsync();
411 await regularDmbDisposeTask;
419 (await semaphoreLockTask).Dispose();
428 ArgumentNullException.ThrowIfNull(parameters);
434 Logger.LogWarning(
"Ignoring bridge request from session without confirmed DMAPI!");
438 Logger.LogTrace(
"Handling bridge request...");
465 =>
SendCommand(parameters,
false, cancellationToken);
473 Logger.LogTrace(
"Changing reboot state to {newRebootState}", newRebootState);
475 ReattachInformation.RebootState = newRebootState;
480 return result !=
null && result.ErrorMessage ==
null;
487 Logger.LogTrace(
"Resetting reboot state...");
488 ReattachInformation.RebootState =
RebootState.Normal;
504 ReattachInformation.Dmb = dmbProvider ??
throw new ArgumentNullException(nameof(dmbProvider));
509 public async ValueTask
InstanceRenamed(
string newInstanceName, CancellationToken cancellationToken)
512 if (runtimeInformation !=
null)
513 runtimeInformation.InstanceName = newInstanceName;
521 public async ValueTask
UpdateChannels(IEnumerable<ChannelRepresentation> newChannels, CancellationToken cancellationToken)
528 public ValueTask
CreateDump(
string outputFile,
bool minidump, CancellationToken cancellationToken)
552 uint? startupTimeout,
556 var startTime = DateTimeOffset.UtcNow;
557 var useBridgeRequestForLaunchResult = !reattached && (apiValidate ||
DMApiAvailable);
558 var startupTask = useBridgeRequestForLaunchResult
559 ? initialBridgeRequestTcs.Task
563 if (startupTimeout.HasValue)
564 toAwait = Task.WhenAny(
567 TimeSpan.FromSeconds(startupTimeout.Value),
568 CancellationToken.None)
572 "Waiting for LaunchResult based on {launchResultCompletionCause}{possibleTimeout}...",
573 useBridgeRequestForLaunchResult ?
"initial bridge request" :
"process startup",
574 startupTimeout.HasValue ? $
" with a timeout of {startupTimeout.Value}s" : String.Empty);
580 ExitCode = process.Lifetime.IsCompleted ? await process.Lifetime :
null,
581 StartupTime = startupTask.IsCompleted ? (DateTimeOffset.UtcNow - startTime) :
null,
584 Logger.LogTrace(
"Launch result: {launchResult}", result);
586 if (!result.ExitCode.HasValue && reattached && !
disposed)
590 assemblyInformationProvider.
Version,
595 if (reattachResponse !=
null)
597 if (reattachResponse?.CustomCommands !=
null)
598 chatTrackingContext.CustomCommands = reattachResponse.CustomCommands;
599 else if (reattachResponse !=
null)
604 "DMAPI Interop v{interopVersion} isn't returning the TGS custom commands list. Functionality added in v5.2.0.",
624 Logger.LogTrace(
"Entered post validation terminate task.");
625 if (!await proceedTask)
627 Logger.LogTrace(
"Not running post validation terminate task for repeated bridge request.");
631 const int GracePeriodSeconds = 30;
632 Logger.LogDebug(
"Server will terminated in {gracePeriodSeconds}s if it does not exit...", GracePeriodSeconds);
633 var delayTask =
asyncDelayer.
Delay(TimeSpan.FromSeconds(GracePeriodSeconds), CancellationToken.None).AsTask();
638 Logger.LogWarning(
"DMAPI took too long to shutdown server after validation request!");
643 Logger.LogTrace(
"Server exited properly post validation.");
652#pragma warning disable CA1502
663 return BridgeError(
"Missing channelIds field in chatMessage!");
665 if (parameters.
ChatMessage.
ChannelIds.Any(channelIdString => !UInt64.TryParse(channelIdString, out var _)))
666 return BridgeError(
"Invalid channelIds in chatMessage!");
669 return BridgeError(
"Missing message field in chatMessage!");
671 var anyFailed =
false;
675 anyFailed |= !UInt64.TryParse(channelString, out var channelId);
680 return BridgeError(
"Failed to parse channelIds as U64!");
687 Interlocked.Exchange(ref
primeTcs,
new TaskCompletionSource()).SetResult();
690 Logger.LogInformation(
"Bridge requested process termination!");
691 chatTrackingContext.Active =
false;
696 return BridgeError(
"Port switching is no longer supported!");
703 var proceedTcs =
new TaskCompletionSource<bool>();
705 proceedTcs.SetResult(firstValidationRequest);
707 if (!firstValidationRequest)
708 return BridgeError(
"Startup bridge request was repeated!");
711 if (parameters.
Version ==
null)
736 return BridgeError(
"Missing minimumSecurityLevel field!");
738 return BridgeError(
"Invalid minimumSecurityLevel!");
756 var newTopicPort = parameters.
TopicPort.Value;
757 Logger.LogInformation(
"Server is requesting use of port {topicPort} for topic communications", newTopicPort);
758 ReattachInformation.TopicPort = newTopicPort;
762 chatTrackingContext.CustomCommands = parameters.CustomCommands ?? Array.Empty<
CustomCommand>();
763 chatTrackingContext.Active =
true;
764 Interlocked.Exchange(ref
startupTcs,
new TaskCompletionSource()).SetResult();
770 chatTrackingContext.Active =
false;
772 Interlocked.Exchange(ref
rebootTcs,
new TaskCompletionSource()).SetResult();
773 await
rebootGate.WaitAsync(cancellationToken);
788 return BridgeError($
"commandType {parameters.CommandType} not supported!");
793#pragma warning restore CA1502
802 Logger.LogWarning(
"Bridge request error: {message}", message);
805 ErrorMessage = message,
820 if (LogTopicRequests)
821 Logger.LogTrace(
"Topic request: {json}", json);
822 var fullCommandByteCount = Encoding.UTF8.GetByteCount(fullCommandString);
825 return await
SendRawTopic(fullCommandString, topicPriority, cancellationToken);
827 var interopChunkingVersion =
new Version(5, 6, 0);
831 "Cannot send topic request as it is exceeds the single request limit of {limitBytes}B ({actualBytes}B) and requires chunking and the current compile job's interop version must be at least {chunkingVersionRequired}!",
833 fullCommandByteCount,
834 interopChunkingVersion);
841 parameters.AccessIdentifier =
null!;
846 var fullPayloadSize = (uint)json.Length;
848 List<string>? chunkQueryStrings =
null;
849 for (var chunkCount = 2; chunkQueryStrings ==
null; ++chunkCount)
851 var standardChunkSize = fullPayloadSize / chunkCount;
852 var bigChunkSize = standardChunkSize + (fullPayloadSize % chunkCount);
856 chunkQueryStrings =
new List<string>();
857 for (var i = 0U; i < chunkCount; ++i)
859 var startIndex = i * standardChunkSize;
860 var subStringLength = Math.Min(
861 fullPayloadSize - startIndex,
864 : standardChunkSize);
865 var chunkPayload = json.Substring((
int)startIndex, (int)subStringLength);
869 Payload = chunkPayload,
870 PayloadId = payloadId,
872 TotalChunks = (uint)chunkCount,
884 chunkQueryStrings =
null;
888 chunkQueryStrings.Add(chunkCommandString);
892 Logger.LogTrace(
"Chunking topic request ({totalChunks} total)...", chunkQueryStrings.Count);
895 bool LogRequestIssue(
bool possiblyFromCompletedRequest)
900 "Topic request {chunkingStatus} failed!{potentialRequestError}",
901 possiblyFromCompletedRequest ?
"final chunk" :
"chunking",
903 ? $
" Request error: {combinedResponse.InteropResponse.ErrorMessage}"
911 foreach (var chunkCommandString
in chunkQueryStrings)
913 combinedResponse = await
SendRawTopic(chunkCommandString, topicPriority, cancellationToken);
914 if (LogRequestIssue(chunkCommandString == chunkQueryStrings.Last()))
918 while ((combinedResponse?.InteropResponse?.MissingChunks?.Count ?? 0) > 0)
920 Logger.LogWarning(
"DD is still missing some chunks of topic request P{payloadId}! Sending missing chunks...", payloadId);
921 var missingChunks = combinedResponse!.InteropResponse!.MissingChunks!;
922 var lastIndex = missingChunks.Last();
923 foreach (var missingChunkIndex
in missingChunks)
925 var chunkCommandString = chunkQueryStrings[(int)missingChunkIndex];
926 combinedResponse = await
SendRawTopic(chunkCommandString, topicPriority, cancellationToken);
927 if (LogRequestIssue(missingChunkIndex == lastIndex))
932 return combinedResponse;
944 var commandString = String.Format(
945 CultureInfo.InvariantCulture,
949 return commandString;
959 async ValueTask<CombinedTopicResponse?>
SendRawTopic(
string queryString,
bool priority, CancellationToken cancellationToken)
964 "Attempted to send a topic on a disposed SessionController");
969 Byond.TopicSender.TopicResponse? byondResponse;
975 : NullLogger.Instance,
981 if (byondResponse ==
null)
985 "Unable to send priority topic \"{queryString}\"!",
991 var topicReturn = byondResponse.StringData;
994 if (topicReturn !=
null)
1001 Logger.LogWarning(ex,
"Invalid interop response: {topicReturnString}", topicReturn);
1016 ArgumentNullException.ThrowIfNull(parameters);
1021 "Attempted to send a command to an inactive SessionController: {commandType}",
1028 Logger.LogTrace(
"Not sending topic request {commandType} to server without/with incompatible DMAPI!", parameters.
CommandType);
1033 if (!bypassLaunchResult)
1035 var launchResult = await
LaunchResult.WaitAsync(cancellationToken);
1036 if (launchResult.ExitCode.HasValue)
1038 Logger.LogDebug(
"Not sending topic request {commandType} to server that failed to launch!", parameters.
CommandType);
1046 Logger.LogDebug(
"Not sending topic request {commandType} to server that is rebooting/starting.", parameters.
CommandType);
1050 using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
1051 var combinedCancellationToken = cts.Token;
1052 async ValueTask CancelIfLifetimeElapses()
1056 var completed = await Task.WhenAny(
Lifetime, reboot).WaitAsync(combinedCancellationToken);
1059 "Server {action}, cancelling pending command: {commandType}",
1066 catch (OperationCanceledException)
1072 Logger.LogError(ex,
"Error in CancelIfLifetimeElapses!");
1077 var lifetimeWatchingTask = CancelIfLifetimeElapses();
1080 var combinedResponse = await
SendTopicRequest(parameters, combinedCancellationToken);
1082 void LogCombinedResponse()
1084 if (LogTopicRequests && combinedResponse !=
null)
1085 Logger.LogTrace(
"Topic response: {topicString}", combinedResponse.ByondTopicResponse.StringData ??
"(NO STRING DATA)");
1088 LogCombinedResponse();
1090 if (combinedResponse?.InteropResponse?.
Chunk !=
null)
1092 Logger.LogTrace(
"Topic response is chunked...");
1094 ChunkData? nextChunk = combinedResponse.InteropResponse.Chunk;
1097 var nextRequest = await ProcessChunk<TopicResponse, ChunkedTopicParameters>(
1098 (completedResponse, _) =>
1100 fullResponse = completedResponse;
1105 Logger.LogWarning(
"Topic response chunking error: {message}", error);
1108 combinedResponse?.InteropResponse?.
Chunk,
1109 combinedCancellationToken);
1111 if (nextRequest !=
null)
1113 nextRequest.PayloadId = nextChunk.
PayloadId;
1114 combinedResponse = await
SendTopicRequest(nextRequest, combinedCancellationToken);
1115 LogCombinedResponse();
1116 nextChunk = combinedResponse?.InteropResponse?.Chunk;
1121 while (nextChunk !=
null);
1124 fullResponse = combinedResponse?.InteropResponse;
1126 catch (OperationCanceledException ex)
1130 "Topic request {cancellationType}!",
1131 combinedCancellationToken.IsCancellationRequested
1132 ? cancellationToken.IsCancellationRequested
1138 cancellationToken.ThrowIfCancellationRequested();
1143 await lifetimeWatchingTask;
1146 if (fullResponse?.ErrorMessage !=
null)
1148 "Errored topic response for command {commandType}: {errorMessage}",
1152 return fullResponse;
1162 if (invocation ==
null)
1166 if (eventName ==
null)
1170 if (!notifyCompletion.HasValue)
1173 var eventParams =
new List<string>
1178 eventParams.AddRange(invocation
1180 .Where(param => param !=
null)
1182 ?? Enumerable.Empty<
string>());
1184 var eventId = Guid.NewGuid();
1185 Logger.LogInformation(
"Triggering custom event \"{eventName}\": {eventId}", eventName, eventId);
1190 async Task ProcessEvent()
1197 await eventTask.Value;
1205 if (notifyCompletion.Value)
1209 else if (exception ==
null)
1210 Logger.LogTrace(
"Finished custom event {eventId}, not sending notification.", eventId);
1212 if (exception !=
null)
1215 catch (OperationCanceledException ex)
1217 Logger.LogDebug(ex,
"Custom event invocation {eventId} aborted!", eventId);
1221 Logger.LogWarning(ex,
"Custom event invocation {eventId} errored!", eventId);
1225 if (!eventTask.HasValue)
1226 return BridgeError(
"Event refused to execute due to matching a TGS event!");
1231 var eventProcessingTask = ProcessEvent();
1237 EventId = notifyCompletion.Value
1238 ? eventId.ToString()
Information about an engine installation.
EngineType? Engine
The EngineType.
Metadata about a server instance.
Represents a deployment run.
virtual ? Version DMApiVersion
The DMAPI Version.
Represents a command made from DM code.
Parameters for a bridge request.
BridgeCommandType? CommandType
The BridgeCommandType.
ChatMessage? ChatMessage
The Interop.ChatMessage for BridgeCommandType.ChatSend requests.
CustomEventInvocation? EventInvocation
The CustomEventInvocation being triggered.
ushort? TopicPort
The port that should be used to send world topics, if not the default.
DreamDaemonSecurity? MinimumSecurityLevel
The minimum required DreamDaemonSecurity level for BridgeCommandType.Startup requests.
ChunkData? Chunk
The ChunkData for BridgeCommandType.Chunk requests.
Version? Version
The DMAPI global::System.Version for BridgeCommandType.Startup requests.
A response to a bridge request.
Parameters for invoking a custom event.
string? EventName
The name of the event being invoked.
bool? NotifyCompletion
If the DMAPI should be notified when the event compeletes.
ICollection< string >? ChannelIds
The ICollection<T> of Chat.ChannelRepresentation.Ids to sent the MessageContent to....
Represents an update of ChannelRepresentations.
A packet of a split serialized set of data.
uint? PayloadId
The ID of the full request to differentiate different chunkings.Nullable to prevent default value omi...
Class that deserializes chunked interop payloads.
ILogger< Chunker > Logger
The ILogger for the Chunker.
uint NextPayloadId
Gets a payload ID for use in a new ChunkSetInfo.
Constants used for communication with the DMAPI.
static readonly JsonSerializerSettings SerializerSettings
JsonSerializerSettings for use when communicating with the DMAPI.
const uint MaximumTopicRequestLength
The maximum length in bytes of a Byond.TopicSender.ITopicClient payload.
static readonly Version InteropVersion
The DMAPI InteropVersion being used.
const string TopicData
Parameter json is encoded in for topic requests.
Common base for interop parameters.
string AccessIdentifier
Used to identify and authenticate the DreamDaemon instance.
string? ErrorMessage
Any errors in the client's parameters.
string? Text
The message string.
TopicParameters for TopicCommandType.ReceiveChunk.
Parameters for a topic request.
static TopicParameters CreateInstanceRenamedTopicParameters(string newInstanceName)
Initializes a new instance of the TopicParameters class.
TopicCommandType? CommandType
The TopicCommandType.
ChunkData? Chunk
The ChunkData for a partial request.
bool IsPriority
Whether or not the TopicParameters constitute a priority request.
A response to a topic request.
Combines a Byond.TopicSender.TopicResponse with a TopicResponse.
TopicResponse? InteropResponse
The interop TopicResponse, if any.
Represents the result of trying to start a DD process.
async ValueTask InstanceRenamed(string newInstanceName, CancellationToken cancellationToken)
Called when the owning Instance is renamed.A ValueTask representing the running operation.
ValueTask< TopicResponse?> SendCommand(TopicParameters parameters, CancellationToken cancellationToken)
Sends a command to DreamDaemon through /world/Topic().A ValueTask<TResult> resulting in the TopicResp...
async ValueTask< BridgeResponse?> ProcessBridgeCommand(BridgeParameters parameters, CancellationToken cancellationToken)
Handle a set of bridge parameters .
readonly Byond.TopicSender.ITopicClient byondTopicSender
The Byond.TopicSender.ITopicClient for the SessionController.
string DumpFileExtension
The file extension to use for process dumps created from this session.
ApiValidationStatus apiValidationStatus
The ApiValidationStatus for the SessionController.
async ValueTask DisposeAsync()
readonly object synchronizationLock
lock object for port updates and disposed.
DateTimeOffset? LaunchTime
When the process was started.
void AdjustPriority(bool higher)
Set's the owned global::System.Diagnostics.Process.PriorityClass to a non-normal value.
async ValueTask< TopicResponse?> SendCommand(TopicParameters parameters, bool bypassLaunchResult, CancellationToken cancellationToken)
Sends a command to DreamDaemon through /world/Topic().
volatile uint rebootBridgeRequestsProcessing
The number of currently active calls to ProcessBridgeRequest(BridgeParameters, CancellationToken) fro...
readonly IDotnetDumpService dotnetDumpService
The IDotnetDumpService for the SessionController.
readonly Api.Models.Instance metadata
The Instance metadata.
Task OnReboot
A Task that completes when the server calls /world/TgsReboot().
bool DMApiAvailable
If the DMAPI may be used this session.
readonly TaskCompletionSource initialBridgeRequestTcs
The TaskCompletionSource that completes when DD makes it's first bridge request.
bool terminationWasIntentional
Backing field for overriding TerminationWasIntentional.
bool disposed
If the SessionController has been disposed.
void SuspendProcess()
Suspends the process.
void ResetRebootState()
Changes RebootState to RebootState.Normal without telling the DMAPI.
readonly IEngineExecutableLock engineLock
The IEngineExecutableLock for the SessionController.
readonly IAsyncDelayer asyncDelayer
The IAsyncDelayer for the SessionController.
long? StartupBridgeRequestsReceived
The number of times a startup bridge request has been received. null if DMApiAvailable is false.
async ValueTask< BridgeResponse?> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
Handle a set of bridge parameters .A ValueTask<TResult> resulting in the BridgeResponse for the reque...
ReattachInformation ReattachInformation
The up to date Session.ReattachInformation.
volatile Task rebootGate
Backing field for RebootGate.
bool TerminationWasIntentional
If the DreamDaemon instance sent a.
readonly IEventConsumer eventConsumer
The IEventConsumer for the SessionController.
BridgeResponse BridgeError(string message)
Log and return a BridgeResponse for a given message .
bool released
If process should be kept alive instead.
readonly IChatManager chat
The IChatManager for the SessionController.
double MeasureProcessorTimeDelta()
Gets the estimated CPU usage fraction of the process based on the last time this was called....
readonly IChatTrackingContext chatTrackingContext
The IChatTrackingContext for the SessionController.
Task< int?> Lifetime
The Task<TResult> resulting in the exit code of the process or null if the process was detached.
readonly CancellationTokenSource sessionDurationCts
A CancellationTokenSource used for tasks that should not exceed the lifetime of the session.
ValueTask CreateDump(string outputFile, bool minidump, CancellationToken cancellationToken)
Create a dump file of the process.A ValueTask representing the running operation.
volatile TaskCompletionSource startupTcs
The TaskCompletionSource that completes when DD sends a valid startup bridge request.
async Task PostValidationShutdown(Task< bool > proceedTask)
Terminates the server after ten seconds if it does not exit.
void ResumeProcess()
Resumes the process.
SessionController(ReattachInformation reattachInformation, Api.Models.Instance metadata, IProcess process, IEngineExecutableLock engineLock, Byond.TopicSender.ITopicClient byondTopicSender, IChatTrackingContext chatTrackingContext, IBridgeRegistrar bridgeRegistrar, IChatManager chat, IAssemblyInformationProvider assemblyInformationProvider, IAsyncDelayer asyncDelayer, IDotnetDumpService dotnetDumpService, IEventConsumer eventConsumer, ILogger< SessionController > logger, Func< ValueTask > postLifetimeCallback, uint? startupTimeout, bool reattached, bool apiValidate)
Initializes a new instance of the SessionController class.
readonly bool apiValidationSession
If this session is meant to validate the presence of the DMAPI.
FifoSemaphore TopicSendSemaphore
The FifoSemaphore used to prevent concurrent calls into /world/Topic().
async ValueTask UpdateChannels(IEnumerable< ChannelRepresentation > newChannels, CancellationToken cancellationToken)
Called when newChannels are set.A ValueTask representing the running operation.
string GenerateQueryString(TopicParameters parameters, out string json)
Generates a Byond.TopicSender.ITopicClient query string for a given set of parameters .
void CheckDisposed()
Throws an ObjectDisposedException if DisposeAsync has been called.
readonly? IBridgeRegistration bridgeRegistration
The IBridgeRegistration for the SessionController.
long? MemoryUsage
Gets the process' memory usage in bytes.
async Task< LaunchResult > GetLaunchResult(IAssemblyInformationProvider assemblyInformationProvider, IAsyncDelayer asyncDelayer, uint? startupTimeout, bool reattached, bool apiValidate)
The Task<TResult> for LaunchResult.
IAsyncDisposable ReplaceDmbProvider(IDmbProvider dmbProvider)
Replace the IDmbProvider in use with a given newProvider , disposing the old one.An IAsyncDisposable ...
Task OnStartup
A Task that completes when the server calls /world/TgsNew().
bool ProcessingRebootBridgeRequest
If the ISessionController is currently processing a bridge request from TgsReboot().
ValueTask Release()
Releases the IProcess without terminating it. Also calls IDisposable.Dispose.A ValueTask representing...
volatile? Task postValidationShutdownTask
Task for shutting down the server if it is taking too long after validation.
volatile Task customEventProcessingTask
The Task representing calls to TriggerCustomEvent(CustomEventInvocation?).
Task OnPrime
A Task that completes when the server calls /world/TgsInitializationComplete().
async ValueTask< CombinedTopicResponse?> SendTopicRequest(TopicParameters parameters, CancellationToken cancellationToken)
Send a topic request for given parameters to DreamDaemon, chunking it if necessary.
volatile TaskCompletionSource rebootTcs
The TaskCompletionSource that completes when DD tells us about a reboot.
async ValueTask< CombinedTopicResponse?> SendRawTopic(string queryString, bool priority, CancellationToken cancellationToken)
Send a given queryString to DreamDaemon's /world/Topic.
volatile TaskCompletionSource primeTcs
The TaskCompletionSource that completes when DD tells us it's primed.
async ValueTask< bool > SetRebootState(RebootState newRebootState, CancellationToken cancellationToken)
Attempts to change the current RebootState to newRebootState .A ValueTask<TResult> resulting in true ...
Task RebootGate
A Task that must complete before a TgsReboot() bridge request can complete.
Version? DMApiVersion
The DMAPI Version.
readonly IProcess process
The IProcess for the SessionController.
BridgeResponse TriggerCustomEvent(CustomEventInvocation? invocation)
Trigger a custom event from a given invocation .
A first-in first-out async semaphore.
async ValueTask< SemaphoreSlimContext > Lock(CancellationToken cancellationToken)
Locks the FifoSemaphore.
Helpers for manipulating the Serilog.Context.LogContext.
const string InstanceIdContextProperty
The Serilog.Context.LogContext property name for Models.Instance Api.Models.EntityId....
Notifyee of when ChannelRepresentations in a IChatTrackingContext are updated.
For managing connected chat services.
void QueueMessage(MessageContent message, IEnumerable< ulong > channelIds)
Queue a chat message to a given set of channelIds .
Represents a tracking of dynamic chat json files.
bool Active
If the CustomCommands should be used.
void SetChannelSink(IChannelSink channelSink)
Sets the channelSink for the IChatTrackingContext.
Provides absolute paths to the latest compiled .dmbs.
void KeepAlive()
Disposing the IDmbProvider won't cause a cleanup of the working directory.
EngineVersion EngineVersion
The Api.Models.EngineVersion used to build the .dmb.
string Directory
The primary game directory.
Models.CompileJob CompileJob
The CompileJob of the .dmb.
Represents usage of the two primary BYOND server executables.
void DoNotDeleteThisSession()
Call if, during a detach, this version should not be deleted.
bool UseDotnetDump
If dotnet-dump should be used to create process dumps for this installation.
ValueTask StopServerProcess(ILogger logger, IProcess process, string accessIdentifier, ushort port, CancellationToken cancellationToken)
Kills a given engine server process .
Consumes EventTypes and takes the appropriate actions.
ValueTask? HandleCustomEvent(string eventName, IEnumerable< string?> parameters, CancellationToken cancellationToken)
Handles a given custom event.
Registers IBridgeHandlers.
IBridgeRegistration RegisterHandler(IBridgeHandler bridgeHandler)
Register a given bridgeHandler .
Represents a registration of an interop session.
Handles communication with a DreamDaemon IProcess.
Service for managing the dotnet-dump installation.
ValueTask Dump(IProcess process, string outputFile, bool minidump, CancellationToken cancellationToken)
Attempt to dump a given process .
void SuspendProcess()
Suspends the process.
void ResumeProcess()
Resumes the process.
void AdjustPriority(bool higher)
Set's the owned global::System.Diagnostics.Process.PriorityClass to a non-normal value.
long? MemoryUsage
Gets the process' memory usage in bytes.
double MeasureProcessorTimeDelta()
Gets the estimated CPU usage fraction of the process based on the last time this was called.
DateTimeOffset? LaunchTime
When the process was started.
ValueTask CreateDump(string outputFile, bool minidump, CancellationToken cancellationToken)
Create a dump file of the process.
Task< int?> Lifetime
The Task<TResult> resulting in the exit code of the process or null if the process was detached.
Abstraction over a global::System.Diagnostics.Process.
Task Startup
The Task representing the time until the IProcess becomes "idle".
void Terminate()
Asycnhronously terminates the process.
For waiting asynchronously.
ValueTask Delay(TimeSpan timeSpan, CancellationToken cancellationToken)
Create a Task that completes after a given timeSpan .
DreamDaemonSecurity
DreamDaemon's security level.
EngineType
The type of engine the codebase is using.
@ Byond
Build your own net dream.
BridgeCommandType
Represents the BridgeParameters.CommandType.
@ Chunk
DreamDaemon attempting to send a longer bridge message.
RebootState
Represents the action to take when /world/Reboot() is called.
ApiValidationStatus
Status of DMAPI validation.