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!");
88 var tcs =
new TaskCompletionSource<Task>();
91 var toAwait = await tcs.Task;
96 tcs.SetResult(Interlocked.Exchange(ref
rebootGate, Wrap()));
282 ILogger<SessionController> logger,
283 Func<ValueTask> postLifetimeCallback,
284 uint? startupTimeout,
289 ReattachInformation = reattachInformation ??
throw new ArgumentNullException(nameof(reattachInformation));
290 this.metadata =
metadata ??
throw new ArgumentNullException(nameof(
metadata));
291 this.process =
process ??
throw new ArgumentNullException(nameof(
process));
295 ArgumentNullException.ThrowIfNull(bridgeRegistrar);
297 this.chat =
chat ??
throw new ArgumentNullException(nameof(
chat));
298 ArgumentNullException.ThrowIfNull(assemblyInformationProvider);
312 primeTcs =
new TaskCompletionSource();
333 "Not registering session with {reasonWhyDmApiIsBad} DMAPI version for interop!",
336 : $
"incompatible ({reattachInformation.Dmb.CompileJob.DMApiVersion})");
338 async Task<int?> WrapLifetime()
341 await postLifetimeCallback();
351 assemblyInformationProvider,
358 "Created session controller. CommsKey: {accessIdentifier}, Port: {port}",
360 reattachInformation.
Port);
373 Logger.LogTrace(
"Disposing...");
376 var cancellationToken = CancellationToken.None;
394 if (initialDmb !=
null)
395 await initialDmb.DisposeAsync();
397 await regularDmbDisposeTask;
405 (await semaphoreLockTask).Dispose();
414 ArgumentNullException.ThrowIfNull(parameters);
418 Logger.LogTrace(
"Handling bridge request...");
445 =>
SendCommand(parameters,
false, cancellationToken);
453 Logger.LogTrace(
"Changing reboot state to {newRebootState}", newRebootState);
455 ReattachInformation.RebootState = newRebootState;
460 return result !=
null && result.ErrorMessage ==
null;
467 Logger.LogTrace(
"Resetting reboot state...");
468 ReattachInformation.RebootState =
RebootState.Normal;
484 ReattachInformation.Dmb = dmbProvider ??
throw new ArgumentNullException(nameof(dmbProvider));
489 public async ValueTask
InstanceRenamed(
string newInstanceName, CancellationToken cancellationToken)
492 if (runtimeInformation !=
null)
493 runtimeInformation.InstanceName = newInstanceName;
501 public async ValueTask
UpdateChannels(IEnumerable<ChannelRepresentation> newChannels, CancellationToken cancellationToken)
508 public ValueTask
CreateDump(
string outputFile,
bool minidump, CancellationToken cancellationToken)
528 uint? startupTimeout,
532 var startTime = DateTimeOffset.UtcNow;
533 var useBridgeRequestForLaunchResult = !reattached && (apiValidate ||
DMApiAvailable);
534 var startupTask = useBridgeRequestForLaunchResult
535 ? initialBridgeRequestTcs.Task
539 if (startupTimeout.HasValue)
540 toAwait = Task.WhenAny(
543 TimeSpan.FromSeconds(startupTimeout.Value),
544 CancellationToken.None));
547 "Waiting for LaunchResult based on {launchResultCompletionCause}{possibleTimeout}...",
548 useBridgeRequestForLaunchResult ?
"initial bridge request" :
"process startup",
549 startupTimeout.HasValue ? $
" with a timeout of {startupTimeout.Value}s" : String.Empty);
555 ExitCode = process.Lifetime.IsCompleted ? await process.Lifetime :
null,
556 StartupTime = startupTask.IsCompleted ? (DateTimeOffset.UtcNow - startTime) :
null,
559 Logger.LogTrace(
"Launch result: {launchResult}", result);
561 if (!result.ExitCode.HasValue && reattached && !
disposed)
565 assemblyInformationProvider.
Version,
570 if (reattachResponse !=
null)
572 if (reattachResponse?.CustomCommands !=
null)
573 chatTrackingContext.CustomCommands = reattachResponse.CustomCommands;
574 else if (reattachResponse !=
null)
579 "DMAPI Interop v{interopVersion} isn't returning the TGS custom commands list. Functionality added in v5.2.0.",
599 Logger.LogTrace(
"Entered post validation terminate task.");
600 if (!await proceedTask)
602 Logger.LogTrace(
"Not running post validation terminate task for repeated bridge request.");
606 const int GracePeriodSeconds = 30;
607 Logger.LogDebug(
"Server will terminated in {gracePeriodSeconds}s if it does not exit...", GracePeriodSeconds);
608 var delayTask =
asyncDelayer.
Delay(TimeSpan.FromSeconds(GracePeriodSeconds), CancellationToken.None);
613 Logger.LogWarning(
"DMAPI took too long to shutdown server after validation request!");
618 Logger.LogTrace(
"Server exited properly post validation.");
627#pragma warning disable CA1502
638 return BridgeError(
"Missing channelIds field in chatMessage!");
640 if (parameters.
ChatMessage.
ChannelIds.Any(channelIdString => !UInt64.TryParse(channelIdString, out var _)))
641 return BridgeError(
"Invalid channelIds in chatMessage!");
644 return BridgeError(
"Missing message field in chatMessage!");
646 var anyFailed =
false;
650 anyFailed |= !UInt64.TryParse(channelString, out var channelId);
655 return BridgeError(
"Failed to parse channelIds as U64!");
662 Interlocked.Exchange(ref
primeTcs,
new TaskCompletionSource()).SetResult();
665 Logger.LogInformation(
"Bridge requested process termination!");
666 chatTrackingContext.Active =
false;
671 return BridgeError(
"Port switching is no longer supported!");
677 var proceedTcs =
new TaskCompletionSource<bool>();
679 proceedTcs.SetResult(firstValidationRequest);
681 if (!firstValidationRequest)
682 return BridgeError(
"Startup bridge request was repeated!");
685 if (parameters.
Version ==
null)
710 return BridgeError(
"Missing minimumSecurityLevel field!");
712 return BridgeError(
"Invalid minimumSecurityLevel!");
730 var newTopicPort = parameters.
TopicPort.Value;
731 Logger.LogInformation(
"Server is requesting use of port {topicPort} for topic communications", newTopicPort);
732 ReattachInformation.TopicPort = newTopicPort;
736 chatTrackingContext.CustomCommands = parameters.CustomCommands ?? Array.Empty<
CustomCommand>();
737 chatTrackingContext.Active =
true;
738 Interlocked.Exchange(ref
startupTcs,
new TaskCompletionSource()).SetResult();
744 chatTrackingContext.Active =
false;
745 Interlocked.Exchange(ref
rebootTcs,
new TaskCompletionSource()).SetResult();
746 await
RebootGate.WaitAsync(cancellationToken);
761 return BridgeError($
"commandType {parameters.CommandType} not supported!");
766#pragma warning restore CA1502
775 Logger.LogWarning(
"Bridge request error: {message}", message);
778 ErrorMessage = message,
793 if (LogTopicRequests)
794 Logger.LogTrace(
"Topic request: {json}", json);
795 var fullCommandByteCount = Encoding.UTF8.GetByteCount(fullCommandString);
798 return await
SendRawTopic(fullCommandString, topicPriority, cancellationToken);
800 var interopChunkingVersion =
new Version(5, 6, 0);
804 "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}!",
806 fullCommandByteCount,
807 interopChunkingVersion);
814 parameters.AccessIdentifier =
null!;
819 var fullPayloadSize = (uint)json.Length;
821 List<string>? chunkQueryStrings =
null;
822 for (var chunkCount = 2; chunkQueryStrings ==
null; ++chunkCount)
824 var standardChunkSize = fullPayloadSize / chunkCount;
825 var bigChunkSize = standardChunkSize + (fullPayloadSize % chunkCount);
829 chunkQueryStrings =
new List<string>();
830 for (var i = 0U; i < chunkCount; ++i)
832 var startIndex = i * standardChunkSize;
833 var subStringLength = Math.Min(
834 fullPayloadSize - startIndex,
837 : standardChunkSize);
838 var chunkPayload = json.Substring((
int)startIndex, (
int)subStringLength);
842 Payload = chunkPayload,
843 PayloadId = payloadId,
845 TotalChunks = (uint)chunkCount,
857 chunkQueryStrings =
null;
861 chunkQueryStrings.Add(chunkCommandString);
865 Logger.LogTrace(
"Chunking topic request ({totalChunks} total)...", chunkQueryStrings.Count);
868 bool LogRequestIssue(
bool possiblyFromCompletedRequest)
873 "Topic request {chunkingStatus} failed!{potentialRequestError}",
874 possiblyFromCompletedRequest ?
"final chunk" :
"chunking",
875 combinedResponse?.InteropResponse?.ErrorMessage !=
null
876 ? $
" Request error: {combinedResponse.InteropResponse.ErrorMessage}"
884 foreach (var chunkCommandString
in chunkQueryStrings)
886 combinedResponse = await
SendRawTopic(chunkCommandString, topicPriority, cancellationToken);
887 if (LogRequestIssue(chunkCommandString == chunkQueryStrings.Last()))
891 while ((combinedResponse?.InteropResponse?.MissingChunks?.Count ?? 0) > 0)
893 Logger.LogWarning(
"DD is still missing some chunks of topic request P{payloadId}! Sending missing chunks...", payloadId);
894 var missingChunks = combinedResponse!.InteropResponse!.MissingChunks!;
895 var lastIndex = missingChunks.Last();
896 foreach (var missingChunkIndex
in missingChunks)
898 var chunkCommandString = chunkQueryStrings[(int)missingChunkIndex];
899 combinedResponse = await
SendRawTopic(chunkCommandString, topicPriority, cancellationToken);
900 if (LogRequestIssue(missingChunkIndex == lastIndex))
905 return combinedResponse;
917 var commandString = String.Format(
918 CultureInfo.InvariantCulture,
922 return commandString;
932 async ValueTask<CombinedTopicResponse?>
SendRawTopic(
string queryString,
bool priority, CancellationToken cancellationToken)
937 "Attempted to send a topic on a disposed SessionController");
942 Byond.TopicSender.TopicResponse? byondResponse;
948 : NullLogger.Instance,
954 if (byondResponse ==
null)
958 "Unable to send priority topic \"{queryString}\"!",
964 var topicReturn = byondResponse.StringData;
967 if (topicReturn !=
null)
974 Logger.LogWarning(ex,
"Invalid interop response: {topicReturnString}", topicReturn);
989 ArgumentNullException.ThrowIfNull(parameters);
994 "Attempted to send a command to an inactive SessionController: {commandType}",
1001 Logger.LogTrace(
"Not sending topic request {commandType} to server without/with incompatible DMAPI!", parameters.
CommandType);
1006 if (!bypassLaunchResult)
1008 var launchResult = await
LaunchResult.WaitAsync(cancellationToken);
1009 if (launchResult.ExitCode.HasValue)
1011 Logger.LogDebug(
"Not sending topic request {commandType} to server that failed to launch!", parameters.
CommandType);
1019 Logger.LogDebug(
"Not sending topic request {commandType} to server that is rebooting/starting.", parameters.
CommandType);
1023 using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
1024 var combinedCancellationToken = cts.Token;
1025 async ValueTask CancelIfLifetimeElapses()
1029 var completed = await Task.WhenAny(
Lifetime, reboot).WaitAsync(combinedCancellationToken);
1032 "Server {action}, cancelling pending command: {commandType}",
1039 catch (OperationCanceledException)
1045 Logger.LogError(ex,
"Error in CancelIfLifetimeElapses!");
1050 var lifetimeWatchingTask = CancelIfLifetimeElapses();
1053 var combinedResponse = await
SendTopicRequest(parameters, combinedCancellationToken);
1055 void LogCombinedResponse()
1057 if (LogTopicRequests && combinedResponse !=
null)
1058 Logger.LogTrace(
"Topic response: {topicString}", combinedResponse.ByondTopicResponse.StringData ??
"(NO STRING DATA)");
1061 LogCombinedResponse();
1063 if (combinedResponse?.InteropResponse?.Chunk !=
null)
1065 Logger.LogTrace(
"Topic response is chunked...");
1067 ChunkData? nextChunk = combinedResponse.InteropResponse.Chunk;
1070 var nextRequest = await ProcessChunk<TopicResponse, ChunkedTopicParameters>(
1071 (completedResponse, _) =>
1073 fullResponse = completedResponse;
1078 Logger.LogWarning(
"Topic response chunking error: {message}", error);
1081 combinedResponse?.InteropResponse?.Chunk,
1082 combinedCancellationToken);
1084 if (nextRequest !=
null)
1086 nextRequest.PayloadId = nextChunk.
PayloadId;
1087 combinedResponse = await
SendTopicRequest(nextRequest, combinedCancellationToken);
1088 LogCombinedResponse();
1089 nextChunk = combinedResponse?.InteropResponse?.Chunk;
1094 while (nextChunk !=
null);
1097 fullResponse = combinedResponse?.InteropResponse;
1099 catch (OperationCanceledException ex)
1103 "Topic request {cancellationType}!",
1104 combinedCancellationToken.IsCancellationRequested
1105 ? cancellationToken.IsCancellationRequested
1111 cancellationToken.ThrowIfCancellationRequested();
1116 await lifetimeWatchingTask;
1119 if (fullResponse?.ErrorMessage !=
null)
1121 "Errored topic response for command {commandType}: {errorMessage}",
1125 return fullResponse;
1135 if (invocation ==
null)
1139 if (eventName ==
null)
1143 if (!notifyCompletion.HasValue)
1146 var eventParams =
new List<string>
1151 eventParams.AddRange(invocation
1153 .Where(param => param !=
null)
1155 ?? Enumerable.Empty<
string>());
1157 var eventId = Guid.NewGuid();
1158 Logger.LogInformation(
"Triggering custom event \"{eventName}\": {eventId}", eventName, eventId);
1163 async Task ProcessEvent()
1167 await eventTask.Value;
1169 if (notifyCompletion.Value)
1174 Logger.LogTrace(
"Finished custom event {eventId}, not sending notification.", eventId);
1176 catch (OperationCanceledException ex)
1178 Logger.LogDebug(ex,
"Custom event invocation {eventId} aborted!", eventId);
1182 Logger.LogWarning(ex,
"Custom event invocation {eventId} errored!", eventId);
1186 if (!eventTask.HasValue)
1187 return BridgeError(
"Event refused to execute due to matching a TGS event!");
1192 var eventProcessingTask = ProcessEvent();
1198 EventId = notifyCompletion.Value
1199 ? 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 Bridge.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 om...
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.
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 TopicRes...
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.
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.
async ValueTask< BridgeResponse?> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
Handle a set of bridge parameters . A ValueTask<TResult> resulting in the BridgeResponse for the requ...
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.
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.
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 representin...
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.
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.
Task 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.
BridgeCommandType
Represents the BridgeParameters.CommandType.
RebootState
Represents the action to take when /world/Reboot() is called.
ApiValidationStatus
Status of DMAPI validation.