Beispiel #1
0
        /// <summary>
        /// Run a quick DD instance to test the DMAPI is installed on the target code
        /// </summary>
        /// <param name="timeout">The timeout in seconds for validation</param>
        /// <param name="securityLevel">The <see cref="DreamDaemonSecurity"/> level to use to validate the API</param>
        /// <param name="job">The <see cref="Models.CompileJob"/> for the operation</param>
        /// <param name="byondLock">The current <see cref="IByondExecutableLock"/></param>
        /// <param name="portToUse">The port to use for API validation</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
        /// <returns>A <see cref="Task"/> representing the running operation</returns>
        async Task VerifyApi(uint timeout, DreamDaemonSecurity securityLevel, Models.CompileJob job, IByondExecutableLock byondLock, ushort portToUse, CancellationToken cancellationToken)
        {
            logger.LogTrace("Verifying DMAPI...");
            var launchParameters = new DreamDaemonLaunchParameters
            {
                AllowWebClient = false,
                PrimaryPort    = portToUse,
                SecurityLevel  = securityLevel,
                StartupTimeout = timeout
            };

            var dirA = ioManager.ConcatPath(job.DirectoryName.ToString(), ADirectoryName);

            job.MinimumSecurityLevel = securityLevel;             // needed for the TempDmbProvider
            var timeoutAt = DateTimeOffset.Now.AddSeconds(timeout);

            using (var provider = new TemporaryDmbProvider(ioManager.ResolvePath(dirA), String.Concat(job.DmeName, DmbExtension), job))
                using (var controller = await sessionControllerFactory.LaunchNew(launchParameters, provider, byondLock, true, true, true, cancellationToken).ConfigureAwait(false))
                {
                    var launchResult = await controller.LaunchResult.ConfigureAwait(false);

                    var now = DateTimeOffset.Now;
                    if (now < timeoutAt && launchResult.StartupTime.HasValue)
                    {
                        var timeoutTask = Task.Delay(timeoutAt - now, cancellationToken);

                        await Task.WhenAny(controller.Lifetime, timeoutTask).ConfigureAwait(false);

                        cancellationToken.ThrowIfCancellationRequested();
                    }

                    if (controller.Lifetime.IsCompleted)
                    {
                        var validationStatus = controller.ApiValidationStatus;
                        logger.LogTrace("API validation status: {0}", validationStatus);
                        switch (validationStatus)
                        {
                        case ApiValidationStatus.RequiresUltrasafe:
                            job.MinimumSecurityLevel = DreamDaemonSecurity.Ultrasafe;
                            return;

                        case ApiValidationStatus.RequiresSafe:
                            if (securityLevel == DreamDaemonSecurity.Ultrasafe)
                            {
                                throw new JobException("This game must be run with at least the 'Safe' DreamDaemon security level!");
                            }
                            job.MinimumSecurityLevel = DreamDaemonSecurity.Safe;
                            return;

                        case ApiValidationStatus.RequiresTrusted:
                            if (securityLevel != DreamDaemonSecurity.Trusted)
                            {
                                throw new JobException("This game must be run with at least the 'Trusted' DreamDaemon security level!");
                            }
                            job.MinimumSecurityLevel = DreamDaemonSecurity.Trusted;
                            return;

                        case ApiValidationStatus.NeverValidated:
                            break;

                        case ApiValidationStatus.BadValidationRequest:
                            throw new JobException("Recieved an unrecognized API validation request from DreamDaemon!");

                        case ApiValidationStatus.UnaskedValidationRequest:
                        default:
                            throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Session controller returned unexpected ApiValidationStatus: {0}", validationStatus));
                        }
                    }

                    throw new JobException("DMAPI validation timed out!");
                }
        }
        /// <summary>
        /// Run a quick DD instance to test the DMAPI is installed on the target code
        /// </summary>
        /// <param name="timeout">The timeout in seconds for validation</param>
        /// <param name="securityLevel">The <see cref="DreamDaemonSecurity"/> level to use to validate the API</param>
        /// <param name="job">The <see cref="CompileJob"/> for the operation</param>
        /// <param name="byondLock">The current <see cref="IByondExecutableLock"/></param>
        /// <param name="portToUse">The port to use for API validation</param>
        /// <param name="requireValidate">If the API validation is required to complete the deployment.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
        /// <returns>A <see cref="Task"/> representing the running operation</returns>
        async Task VerifyApi(
            uint timeout,
            DreamDaemonSecurity securityLevel,
            Models.CompileJob job,
            IByondExecutableLock byondLock,
            ushort portToUse,
            bool requireValidate,
            CancellationToken cancellationToken)
        {
            logger.LogTrace("Verifying {0}DMAPI...", requireValidate ? "required " : String.Empty);
            var launchParameters = new DreamDaemonLaunchParameters
            {
                AllowWebClient      = false,
                Port                = portToUse,
                SecurityLevel       = securityLevel,
                StartupTimeout      = timeout,
                TopicRequestTimeout = 0,             // not used
                HeartbeatSeconds    = 0              // not used
            };

            job.MinimumSecurityLevel = securityLevel;             // needed for the TempDmbProvider

            ApiValidationStatus validationStatus;

            using (var provider = new TemporaryDmbProvider(ioManager.ResolvePath(job.DirectoryName.ToString()), String.Concat(job.DmeName, DmbExtension), job))
                await using (var controller = await sessionControllerFactory.LaunchNew(provider, byondLock, launchParameters, true, cancellationToken).ConfigureAwait(false))
                {
                    var launchResult = await controller.LaunchResult.ConfigureAwait(false);

                    if (launchResult.StartupTime.HasValue)
                    {
                        await controller.Lifetime.WithToken(cancellationToken).ConfigureAwait(false);
                    }

                    if (!controller.Lifetime.IsCompleted)
                    {
                        await controller.DisposeAsync().ConfigureAwait(false);
                    }

                    validationStatus = controller.ApiValidationStatus;

                    if (requireValidate && validationStatus == ApiValidationStatus.NeverValidated)
                    {
                        throw new JobException(ErrorCode.DreamMakerNeverValidated);
                    }

                    logger.LogTrace("API validation status: {0}", validationStatus);

                    job.DMApiVersion = controller.DMApiVersion;
                }

            switch (validationStatus)
            {
            case ApiValidationStatus.RequiresUltrasafe:
                job.MinimumSecurityLevel = DreamDaemonSecurity.Ultrasafe;
                return;

            case ApiValidationStatus.RequiresSafe:
                job.MinimumSecurityLevel = DreamDaemonSecurity.Safe;
                return;

            case ApiValidationStatus.RequiresTrusted:
                job.MinimumSecurityLevel = DreamDaemonSecurity.Trusted;
                return;

            case ApiValidationStatus.NeverValidated:
                if (requireValidate)
                {
                    throw new JobException(ErrorCode.DreamMakerNeverValidated);
                }
                job.MinimumSecurityLevel = DreamDaemonSecurity.Ultrasafe;
                break;

            case ApiValidationStatus.BadValidationRequest:
            case ApiValidationStatus.Incompatible:
                throw new JobException(ErrorCode.DreamMakerInvalidValidation);

            case ApiValidationStatus.UnaskedValidationRequest:
            default:
                throw new InvalidOperationException(
                          $"Session controller returned unexpected ApiValidationStatus: {validationStatus}");
            }
        }