/// <inheritdoc /> public async Task <BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) { if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } IBridgeHandler bridgeHandler = null; for (var i = 0; bridgeHandler == null && i < 30; ++i) { // There's a miniscule time period where we could potentially receive a bridge request and not have the registration ready when we launch DD // This is a stopgap Task delayTask = Task.CompletedTask; lock (bridgeHandlers) if (!bridgeHandlers.TryGetValue(parameters.AccessIdentifier, out bridgeHandler)) { delayTask = asyncDelayer.Delay(TimeSpan.FromMilliseconds(100), cancellationToken); } await delayTask.ConfigureAwait(false); } if (bridgeHandler == null) { lock (bridgeHandlers) if (!bridgeHandlers.TryGetValue(parameters.AccessIdentifier, out bridgeHandler)) { logger.LogWarning("Recieved invalid bridge request with accees identifier: {0}", parameters.AccessIdentifier); return(null); } } return(await bridgeHandler.ProcessBridgeRequest(parameters, cancellationToken).ConfigureAwait(false)); }
/// <inheritdoc /> public Task <BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) { if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); }
/// <inheritdoc /> public async Task <BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken) { if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } var response = new BridgeResponse(); switch (parameters.CommandType) { case BridgeCommandType.ChatSend: if (parameters.ChatMessage == null) { return new BridgeResponse { ErrorMessage = "Missing chatMessage field!" } } ; if (parameters.ChatMessage.ChannelIds == null) { return new BridgeResponse { ErrorMessage = "Missing channelIds field in chatMessage!" } } ; if (parameters.ChatMessage.ChannelIds.Any(channelIdString => !UInt64.TryParse(channelIdString, out var _))) { return new BridgeResponse { ErrorMessage = "Invalid channelIds in chatMessage!" } } ; if (parameters.ChatMessage.Text == null) { return new BridgeResponse { ErrorMessage = "Missing message field in chatMessage!" } } ; await chat.SendMessage( parameters.ChatMessage.Text, parameters.ChatMessage.ChannelIds.Select(UInt64.Parse), cancellationToken).ConfigureAwait(false); break; case BridgeCommandType.Prime: var oldPrimeTcs = primeTcs; primeTcs = new TaskCompletionSource <object>(); oldPrimeTcs.SetResult(null); break; case BridgeCommandType.Kill: logger.LogInformation("Bridge requested process termination!"); TerminationWasRequested = true; process.Terminate(); break; case BridgeCommandType.PortUpdate: lock (synchronizationLock) { if (!parameters.CurrentPort.HasValue) { /////UHHHH logger.LogWarning("DreamDaemon sent new port command without providing it's own!"); return(new BridgeResponse { ErrorMessage = "Missing stringified port as data parameter!" }); } var currentPort = parameters.CurrentPort.Value; if (!nextPort.HasValue) { reattachInformation.Port = parameters.CurrentPort.Value; // not ready yet, so what we'll do is accept the random port DD opened on for now and change it later when we decide to } else { // nextPort is ready, tell DD to switch to that // if it fails it'll kill itself response.NewPort = nextPort.Value; reattachInformation.Port = nextPort.Value; nextPort = null; // we'll also get here from SetPort so complete that task var tmpTcs = portAssignmentTcs; portAssignmentTcs = null; tmpTcs.SetResult(true); } portClosedForReboot = false; } break; case BridgeCommandType.Startup: apiValidationStatus = ApiValidationStatus.BadValidationRequest; if (parameters.Version == null) { return new BridgeResponse { ErrorMessage = "Missing dmApiVersion field!" } } ; DMApiVersion = parameters.Version; switch (parameters.MinimumSecurityLevel) { case DreamDaemonSecurity.Ultrasafe: apiValidationStatus = ApiValidationStatus.RequiresUltrasafe; break; case DreamDaemonSecurity.Safe: apiValidationStatus = ApiValidationStatus.RequiresSafe; break; case DreamDaemonSecurity.Trusted: apiValidationStatus = ApiValidationStatus.RequiresTrusted; break; case null: return(new BridgeResponse { ErrorMessage = "Missing minimumSecurityLevel field!" }); default: return(new BridgeResponse { ErrorMessage = "Invalid minimumSecurityLevel!" }); } response.RuntimeInformation = reattachInformation.RuntimeInformation; // Load custom commands chatTrackingContext.CustomCommands = parameters.CustomCommands; break; case BridgeCommandType.Reboot: if (ClosePortOnReboot) { chatTrackingContext.Active = false; response.NewPort = 0; portClosedForReboot = true; } var oldRebootTcs = rebootTcs; rebootTcs = new TaskCompletionSource <object>(); oldRebootTcs.SetResult(null); break; case null: response.ErrorMessage = "Missing commandType!"; break; default: response.ErrorMessage = "Requested commandType not supported!"; break; } return(response); }