예제 #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{TResult}"/> resulting in <see langword="true"/> if the DMAPI was successfully validated, <see langword="false"/> otherwise</returns>
        async Task <bool> 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,                   //all it needs to read the file and exit
                StartupTimeout = timeout
            };

            var dirA     = ioManager.ConcatPath(job.DirectoryName.ToString(), ADirectoryName);
            var provider = new TemporaryDmbProvider(ioManager.ResolvePath(dirA), String.Concat(job.DmeName, DmbExtension), job);

            var timeoutAt = DateTimeOffset.Now.AddSeconds(timeout);

            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)
                {
                    logger.LogDebug("API validation timed out!");
                    return(false);
                }

                var validated = controller.ApiValidated;
                logger.LogTrace("API valid: {0}", validated);
                return(validated);
            }
        }
예제 #2
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,                   //all it needs to read the file and exit
                StartupTimeout = timeout
            };

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

            job.MinimumSecurityLevel = securityLevel;                   //needed for the TempDmbProvider
            var provider = new TemporaryDmbProvider(ioManager.ResolvePath(dirA), String.Concat(job.DmeName, DmbExtension), job);

            var timeoutAt = DateTimeOffset.Now.AddSeconds(timeout);

            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!");
            }
        }