Ejemplo n.º 1
0
        /// <inheritdoc />
        public override Task InstallByond(string path, Version version, CancellationToken cancellationToken)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }
            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            // write the scripts for running the ting
            // need to add $ORIGIN to LD_LIBRARY_PATH
            const string StandardScript = "#!/bin/sh\nexport LD_LIBRARY_PATH=\"\\$ORIGIN:$LD_LIBRARY_PATH\"\nBASEDIR=$(dirname \"$0\")\nexec \"$BASEDIR/{0}\" \"$@\"\n";

            var dreamDaemonScript = String.Format(CultureInfo.InvariantCulture, StandardScript, DreamDaemonExecutableName);
            var dreamMakerScript  = String.Format(CultureInfo.InvariantCulture, StandardScript, DreamMakerExecutableName);

            async Task WriteAndMakeExecutable(string pathToScript, string script)
            {
                Logger.LogTrace("Writing script {0}:{1}{2}", pathToScript, Environment.NewLine, script);
                await IOManager.WriteAllBytes(pathToScript, Encoding.ASCII.GetBytes(script), cancellationToken).ConfigureAwait(false);

                postWriteHandler.HandleWrite(IOManager.ResolvePath(pathToScript));
            }

            var basePath = IOManager.ConcatPath(path, ByondManager.BinPath);

            var task = Task.WhenAll(WriteAndMakeExecutable(IOManager.ConcatPath(basePath, DreamDaemonName), dreamDaemonScript), WriteAndMakeExecutable(IOManager.ConcatPath(basePath, DreamMakerName), dreamMakerScript));

            postWriteHandler.HandleWrite(IOManager.ConcatPath(basePath, DreamDaemonExecutableName));
            postWriteHandler.HandleWrite(IOManager.ConcatPath(basePath, DreamMakerExecutableName));

            return(task);
        }
        /// <summary>
        /// Construct a <see cref="WindowsByondInstaller"/>
        /// </summary>
        /// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
        /// <param name="ioManager">The <see cref="IIOManager"/> for the <see cref="ByondInstallerBase"/>.</param>
        /// <param name="logger">The <see cref="ILogger"/> for the <see cref="ByondInstallerBase"/>.</param>
        public WindowsByondInstaller(IProcessExecutor processExecutor, IIOManager ioManager, ILogger <WindowsByondInstaller> logger)
            : base(ioManager, logger)
        {
            this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));

            PathToUserByondFolder = IOManager.ResolvePath(IOManager.ConcatPath(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "BYOND"));

            semaphore        = new SemaphoreSlim(1);
            installedDirectX = false;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Construct a <see cref="WindowsByondInstaller"/>
        /// </summary>
        /// <param name="postWriteHandler">The value of <see cref="postWriteHandler"/></param>
        /// <param name="ioManager">The <see cref="IIOManager"/> for the <see cref="ByondInstallerBase"/>.</param>
        /// <param name="logger">The <see cref="ILogger"/> for the <see cref="ByondInstallerBase"/>.</param>
        public PosixByondInstaller(IPostWriteHandler postWriteHandler, IIOManager ioManager, ILogger <PosixByondInstaller> logger)
            : base(ioManager, logger)
        {
            this.postWriteHandler = postWriteHandler ?? throw new ArgumentNullException(nameof(postWriteHandler));

            PathToUserByondFolder = IOManager.ResolvePath(
                IOManager.ConcatPath(
                    Environment.GetFolderPath(
                        Environment.SpecialFolder.UserProfile),
                    "./byond/cache"));
        }
Ejemplo n.º 4
0
        /// <inheritdoc />
        public override async Task InstallByond(string path, Version version, CancellationToken cancellationToken)
        {
            async Task SetNoPromptTrusted()
            {
                var configPath = IOManager.ConcatPath(path, ByondConfigDir);
                await IOManager.CreateDirectory(configPath, cancellationToken).ConfigureAwait(false);

                await IOManager.WriteAllBytes(IOManager.ConcatPath(configPath, ByondDDConfig), Encoding.UTF8.GetBytes(ByondNoPromptTrustedMode), cancellationToken).ConfigureAwait(false);
            }

            var setNoPromptTrustedModeTask = SetNoPromptTrusted();

            // after this version lummox made DD depend of directx lol
            // but then he became amazing and not only fixed it but also gave us 30s compiles \[T]/
            // then he readded it again so -_-
            if (!installedDirectX)
            {
                using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
                    if (!installedDirectX)
                    {
                        // ^check again because race conditions
                        // always install it, it's pretty fast and will do better redundancy checking than us
                        var rbdx = IOManager.ConcatPath(path, ByondDXDir);

                        // noShellExecute because we aren't doing runas shennanigans
                        IProcess directXInstaller;
                        try
                        {
                            directXInstaller = processExecutor.LaunchProcess(IOManager.ConcatPath(rbdx, "DXSETUP.exe"), rbdx, "/silent", noShellExecute: true);
                        }
                        catch (Exception e)
                        {
                            throw new JobException("Unable to start DirectX installer process! Is the server running with admin privileges?", e);
                        }

                        using (directXInstaller)
                        {
                            int exitCode;
                            using (cancellationToken.Register(() => directXInstaller.Terminate()))
                                exitCode = await directXInstaller.Lifetime.ConfigureAwait(false);
                            cancellationToken.ThrowIfCancellationRequested();

                            if (exitCode != 0)
                            {
                                throw new JobException(String.Format(CultureInfo.InvariantCulture, "Failed to install included DirectX! Exit code: {0}", exitCode));
                            }
                            installedDirectX = true;
                        }
                    }
            }

            await setNoPromptTrustedModeTask.ConfigureAwait(false);
        }
        /// <summary>
        /// Creates the BYOND cfg file that prevents the trusted mode dialog from appearing when launching DreamDaemon.
        /// </summary>
        /// <param name="path">The path to the BYOND installation.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
        /// <returns>A <see cref="Task"/> representing the running operation.</returns>
        async Task SetNoPromptTrusted(string path, CancellationToken cancellationToken)
        {
            var configPath = IOManager.ConcatPath(path, ByondConfigDir);
            await IOManager.CreateDirectory(configPath, cancellationToken).ConfigureAwait(false);

            var configFilePath = IOManager.ConcatPath(configPath, ByondDDConfig);

            Logger.LogTrace("Disabling trusted prompts in {0}...", configFilePath);
            await IOManager.WriteAllBytes(
                configFilePath,
                Encoding.UTF8.GetBytes(ByondNoPromptTrustedMode),
                cancellationToken)
            .ConfigureAwait(false);
        }
Ejemplo n.º 6
0
 /// <inheritdoc />
 public override async Task CleanCache(CancellationToken cancellationToken)
 {
     try
     {
         await IOManager.DeleteDirectory(IOManager.ConcatPath(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "byond/cache"), cancellationToken).ConfigureAwait(false);
     }
     catch (OperationCanceledException)
     {
         throw;
     }
     catch (Exception e)
     {
         Logger.LogWarning("Error deleting BYOND cache! Exception: {0}", e);
     }
 }
 /// <inheritdoc />
 public async Task CleanCache(CancellationToken cancellationToken)
 {
     try
     {
         Logger.LogDebug("Cleaning BYOND cache...");
         await IOManager.DeleteDirectory(
             IOManager.ConcatPath(
                 PathToUserByondFolder,
                 CacheDirectoryName),
             cancellationToken)
         .ConfigureAwait(false);
     }
     catch (OperationCanceledException)
     {
         throw;
     }
     catch (Exception e)
     {
         Logger.LogWarning("Error deleting BYOND cache! Exception: {0}", e);
     }
 }
        /// <summary>
        /// Attempt to install the DirectX redistributable included with BYOND.
        /// </summary>
        /// <param name="path">The path to the BYOND installation.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
        /// <returns>A <see cref="Task"/> representing the running operation.</returns>
        async Task InstallDirectX(string path, CancellationToken cancellationToken)
        {
            using var lockContext = await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false);

            if (installedDirectX)
            {
                Logger.LogTrace("DirectX already installed.");
                return;
            }

            Logger.LogTrace("Installing DirectX redistributable...");

            // always install it, it's pretty fast and will do better redundancy checking than us
            var rbdx = IOManager.ConcatPath(path, ByondDXDir);

            try
            {
                // noShellExecute because we aren't doing runas shennanigans
                using var directXInstaller = processExecutor.LaunchProcess(
                          IOManager.ConcatPath(rbdx, "DXSETUP.exe"),
                          rbdx,
                          "/silent",
                          noShellExecute: true);

                int exitCode;
                using (cancellationToken.Register(() => directXInstaller.Terminate()))
                    exitCode = await directXInstaller.Lifetime.ConfigureAwait(false);
                cancellationToken.ThrowIfCancellationRequested();

                if (exitCode != 0)
                {
                    throw new JobException(ErrorCode.ByondDirectXInstallFail, new JobException($"Invalid exit code: {exitCode}"));
                }
                installedDirectX = true;
            }
            catch (Exception e)
            {
                throw new JobException(ErrorCode.ByondDirectXInstallFail, e);
            }
        }
        /// <summary>
        /// Attempt to add the DreamDaemon executable as an exception to the Windows firewall.
        /// </summary>
        /// <param name="path">The path to the BYOND installation.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
        /// <returns>A <see cref="Task"/> representing the running operation.</returns>
        async Task AddDreamDaemonToFirewall(string path, CancellationToken cancellationToken)
        {
            var dreamDaemonPath = IOManager.ResolvePath(
                IOManager.ConcatPath(
                    path,
                    ByondManager.BinPath,
                    DreamDaemonName));

            try
            {
                using var netshProcess = processExecutor.LaunchProcess(
                          "netsh.exe",
                          IOManager.ResolvePath(),
                          $"advfirewall firewall add rule name=\"TGS DreamDaemon\" program=\"{dreamDaemonPath}\" protocol=tcp dir=in enable=yes action=allow",
                          true,
                          true,
                          true);

                int exitCode;
                using (cancellationToken.Register(() => netshProcess.Terminate()))
                    exitCode = await netshProcess.Lifetime.ConfigureAwait(false);
                cancellationToken.ThrowIfCancellationRequested();

                Logger.LogDebug(
                    "netsh.exe output:{0}{1}",
                    Environment.NewLine,
                    await netshProcess.GetCombinedOutput(cancellationToken).ConfigureAwait(false));

                if (exitCode != 0)
                {
                    throw new JobException(ErrorCode.ByondDreamDaemonFirewallFail, new JobException($"Invalid exit code: {exitCode}"));
                }
            }
            catch (Exception ex)
            {
                throw new JobException(ErrorCode.ByondDreamDaemonFirewallFail, ex);
            }
        }