예제 #1
0
        List <ProcessListEntry> GetProcessList(IProcessListRequest request)
        {
            // TODO: Use single cancelable task for both actions
            try
            {
                var enableSshAction = _actionRecorder.CreateToolAction(ActionType.GameletEnableSsh);
                if (!_cancelableTaskFactory
                    .Create(TaskMessages.EnablingSSH,
                            async _ =>
                            await _sshManager.EnableSshAsync(Gamelet, enableSshAction))
                    .RunAndRecord(enableSshAction))
                {
                    return(new List <ProcessListEntry>());
                }
            }
            catch (Exception e) when(e is SshKeyException || e is CloudException)
            {
                Trace.WriteLine(e.ToString());
                _dialogUtil.ShowError(ErrorStrings.FailedToEnableSsh(e.Message), e.ToString());
                return(new List <ProcessListEntry>());
            }

            // TODO: Handle ProcessException
            var processListAction  = _actionRecorder.CreateToolAction(ActionType.ProcessList);
            var queryProcessesTask = _cancelableTaskFactory.Create(
                "Querying instance processes...",
                async() => await request.GetBySshAsync(new SshTarget(Gamelet)));

            queryProcessesTask.RunAndRecord(processListAction);
            return(queryProcessesTask.Result);
        }
예제 #2
0
        public IVsiGameLaunch CreateLaunch(LaunchParams launchParams)
        {
            IAction            action     = _actionRecorder.CreateToolAction(ActionType.GameLaunchCreate);
            CreateLaunchResult launchRes  = null;
            ICancelableTask    launchTask = _cancelableTaskFactory.Create(
                TaskMessages.LaunchingGame,
                async task => { launchRes = await CreateLaunchAsync(launchParams, task, action); });

            try
            {
                if (!launchTask.RunAndRecord(action))
                {
                    Trace.WriteLine("Launching a game has been canceled by user.");
                    return(null);
                }
            }
            catch (ConfigurationException e)
            {
                _dialogUtil.ShowError(e.Message);
                return(null);
            }
            catch (CloudException e)
            {
                string message = $"{ErrorStrings.CouldNotStartTheGame}{Environment.NewLine}" +
                                 $"{e.Message}{Environment.NewLine}{Environment.NewLine}{ErrorStrings.SeeLogs}";
                _dialogUtil.ShowError(message);
                return(null);
            }

            if (!string.IsNullOrWhiteSpace(launchRes.WarningMessage))
            {
                _dialogUtil.ShowWarning(launchRes.WarningMessage);
            }

            if (!string.IsNullOrWhiteSpace(launchRes.SdkCompatibilityMessage))
            {
                bool showAgain = _dialogUtil.ShowOkNoMoreDisplayWarning(
                    launchRes.SdkCompatibilityMessage, new[]
                {
                    "Tools", "Options", "Stadia SDK", "Game launch",
                    "SDK incompatibility warning"
                });
                if (!showAgain)
                {
                    _vsiService.Options.AddSdkVersionsToHide(launchParams.GameletSdkVersion,
                                                             launchParams.SdkVersion,
                                                             launchParams.GameletName);
                }
            }

            return(launchRes.GameLaunch);
        }
        public async Task <bool> ShouldAttachToIncosistentCoreFileAsync(DumpReadWarning warning)
        {
            await _taskContext.Factory.SwitchToMainThreadAsync();

            string dialogMessage = null;
            string dialogTitle   = null;

            switch (warning)
            {
            case DumpReadWarning.FileDoesNotExist:
                _dialogUtil.ShowError(ErrorStrings.CoreFileDoesNotExist);
                return(false);

            case DumpReadWarning.ElfHeaderIsCorrupted:
                dialogTitle   = ErrorStrings.DialogTitleWarning;
                dialogMessage = ErrorStrings.CoreFileCorruptedWarningMessage;
                break;

            case DumpReadWarning.FileIsTruncated:
                dialogTitle   = ErrorStrings.DialogTitleWarning;
                dialogMessage = ErrorStrings.CoreFileTruncatedWarningMessage;
                break;

            case DumpReadWarning.ExecutableBuildIdMissing:
                dialogTitle   = ErrorStrings.CoreAttachBuildIdMissingWarningTitle;
                dialogMessage = ErrorStrings.CoreAttachBuildIdMissingWarningMessage;
                break;

            case DumpReadWarning.None:
                break;
            }

            return(_dialogUtil.ShowYesNoWarning(dialogMessage, dialogTitle));
        }
예제 #4
0
        List <string> ReadMountsContentOrDefault(Gamelet gamelet, ActionRecorder actionRecorder)
        {
            List <string>   content       = new List <string>();
            ICancelableTask getMountsTask =
                _cancelableTaskFactory.Create(TaskMessages.CheckingMountInfo, async _ => {
                content = await _remoteCommand.RunWithSuccessCapturingOutputAsync(
                    new SshTarget(gamelet), ReadMountsCmd) ?? new List <string>();
            });

            try
            {
                getMountsTask.RunAndRecord(actionRecorder, ActionType.GameletReadMounts);
                return(content);
            }
            catch (ProcessException e)
            {
                Trace.WriteLine($"Error reading /proc/mounts file: {e.Message}");
                _dialogUtil.ShowError(ErrorStrings.FailedToStartRequiredProcess(e.Message),
                                      e.ToString());
                return(content);
            }
            finally
            {
                string joinedContent = string.Join("\n\t", content);
                Trace.WriteLine($"Gamelet /proc/mounts:{Environment.NewLine}{joinedContent}");
            }
        }
예제 #5
0
 /// <summary>
 /// Enable SSH for communication with the gamelet.
 /// </summary>
 bool EnableSsh(Gamelet gamelet)
 {
     try
     {
         IAction         action        = _actionRecorder.CreateToolAction(ActionType.GameletEnableSsh);
         ICancelableTask enableSshTask =
             _cancelableTaskFactory.Create(TaskMessages.EnablingSSH, async _ => {
             await _sshManager.EnableSshAsync(gamelet, action);
         });
         return(enableSshTask.RunAndRecord(action));
     }
     catch (Exception e) when(e is CloudException || e is SshKeyException)
     {
         Trace.Write($"Received exception while enabling ssh.\n{e}");
         _dialogUtil.ShowError(ErrorStrings.FailedToEnableSsh(e.Message), e.ToString());
         return(false);
     }
 }
예제 #6
0
        public int AddPort(IDebugPortRequest2 request, out IDebugPort2 port)
        {
            var debugSessionMetrics = new DebugSessionMetrics(_metrics);

            debugSessionMetrics.UseNewDebugSessionId();
            var actionRecorder = new ActionRecorder(debugSessionMetrics);

            port = null;

            if (request.GetPortName(out string gameletIdOrName) != VSConstants.S_OK)
            {
                return(VSConstants.E_FAIL);
            }

            var action        = actionRecorder.CreateToolAction(ActionType.GameletGet);
            var gameletClient = _gameletClientFactory.Create(_cloudRunner.Intercept(action));
            var gameletTask   = _cancelableTaskFactory.Create(
                "Querying instance...",
                async() => await gameletClient.LoadByNameOrIdAsync(gameletIdOrName));

            try
            {
                gameletTask.RunAndRecord(action);
            }
            catch (CloudException e)
            {
                Trace.WriteLine(e.ToString());
                _dialogUtil.ShowError(e.Message);
                return(VSConstants.S_OK);
            }

            var debugPort = _debugPortFactory.Create(gameletTask.Result, this,
                                                     debugSessionMetrics.DebugSessionId);

            _ports.Add(debugPort);
            port = debugPort;
            return(VSConstants.S_OK);
        }
        public void TestClearLogsFailsReturnsFalse()
        {
            _remoteCommand
            .When(m => m.RunWithSuccessAsync(new SshTarget(_gamelet1),
                                             GameletSelectorLegacyFlow.ClearLogsCmd))
            .Do(c => { throw new ProcessException("Oops!"); });

            Gamelet gamelet;
            var     result = _gameletSelector.TrySelectAndPrepareGamelet(_targetPath, _deploy,
                                                                         new List <Gamelet> {
                _gamelet1
            }, null, _devAccount, out gamelet);

            Assert.That(result, Is.False);
            _dialogUtil.ShowError(Arg.Any <string>(), Arg.Any <string>());
            AssertMetricRecorded(DeveloperEventType.Types.Type.VsiGameletsClearLogs,
                                 DeveloperEventStatus.Types.Code.ExternalToolUnavailable);
        }
예제 #8
0
        public bool WaitUntilGameLaunched()
        {
            IAction         action = _actionRecorder.CreateToolAction(ActionType.GameLaunchWaitForStart);
            ICancelableTask pollForLaunchStatusTask = _cancelableTaskFactory.Create(
                TaskMessages.LaunchingGame,
                async task => await PollForLaunchStatusAsync(task, action));

            try
            {
                if (!pollForLaunchStatusTask.RunAndRecord(action))
                {
                    Trace.WriteLine("Polling for the launch status has been canceled by user.");
                    return(false);
                }
            }
            catch (Exception e) when(e is TimeoutException || e is GameLaunchFailError)
            {
                Trace.WriteLine(e.Message);
                _dialogUtil.ShowError(e.Message);
                return(false);
            }

            return(true);
        }
예제 #9
0
 public ExitDialogUtil(IDialogUtil dialogUtil, DialogExecutionContext executionContext)
 {
     showErrorDialogWithDetails = (message, details) =>
                                  executionContext(() => dialogUtil.ShowError(message, details));
     showErrorDialog = message => executionContext(() => dialogUtil.ShowError(message));
 }
예제 #10
0
        void AttachClick(object sender, RoutedEventArgs e)
        {
            _taskContext.ThrowIfNotOnMainThread();

            // Figure out core file path
            CoreListEntry?coreListEntry = null;

            if (TabControl.SelectedContent == GameletGroupBox)
            {
                coreListEntry = (CoreListEntry?)CoreList.SelectedItem;
                if (coreListEntry == null)
                {
                    _dialogUtil.ShowError(ErrorStrings.NoCoreFileSelected);
                    return;
                }
            }

            string coreFilePath = null;
            bool   deleteAfter  = false;

            if (TabControl.SelectedContent == LocalGroupBox)
            {
                coreFilePath = LocalCorePathBox.Text;
            }
            else if (TabControl.SelectedContent == GameletGroupBox)
            {
                var tempPath = Path.GetTempPath();
                try
                {
                    _cancelableTaskFactory
                    .Create(TaskMessages.DownloadingCoreFile,
                            async task => await _remoteFile.GetAsync(new SshTarget(_instance),
                                                                     "/usr/local/cloudcast/core/" +
                                                                     coreListEntry?.Name,
                                                                     tempPath, task))
                    .RunAndRecord(_actionRecorder, ActionType.CrashDumpDownload);
                }
                catch (ProcessException ex)
                {
                    Trace.WriteLine($"Failed to download core file.{Environment.NewLine}" +
                                    $"{ex}");
                    _dialogUtil.ShowError(ErrorStrings.FailedToDownloadCore(ex.Message),
                                          ex.ToString());
                    return;
                }

                coreFilePath = Path.Combine(tempPath, coreListEntry?.Name);
                deleteAfter  = true;
            }

            if (string.IsNullOrEmpty(coreFilePath))
            {
                ShowMessage(ErrorStrings.FailedToRetrieveCoreFilePath);
                return;
            }

            // Check if we have a debugger (should always be the case).
            var vsDebugger =
                (IVsDebugger4)ServiceProvider.GlobalProvider.GetService(typeof(IVsDebugger));

            if (vsDebugger == null)
            {
                ShowMessage(ErrorStrings.FailedToStartDebugger);
                return;
            }

            try
            {
                _actionRecorder.RecordToolAction(ActionType.CrashDumpAttach, delegate
                {
                    _taskContext.ThrowIfNotOnMainThread();

                    VsDebugTargetInfo4[] debugTargets = new VsDebugTargetInfo4[1];
                    debugTargets[0].dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess;

                    // LaunchDebugTargets4() throws an exception if |bstrExe| and |bstrCurDir|
                    // are empty. Use core path and temp directory as placeholders.
                    debugTargets[0].bstrExe                = coreFilePath;
                    debugTargets[0].bstrCurDir             = Path.GetTempPath();
                    var parameters                         = _paramsFactory.Create();
                    parameters.CoreFilePath                = coreFilePath;
                    parameters.DebugSessionId              = _debugSessionMetrics.DebugSessionId;
                    parameters.DeleteCoreFile              = deleteAfter;
                    debugTargets[0].bstrOptions            = _paramsFactory.Serialize(parameters);
                    debugTargets[0].guidLaunchDebugEngine  = YetiConstants.DebugEngineGuid;
                    VsDebugTargetProcessInfo[] processInfo =
                        new VsDebugTargetProcessInfo[debugTargets.Length];
                    vsDebugger.LaunchDebugTargets4(1, debugTargets, processInfo);
                });
            }
            catch (COMException except)
            {
                Trace.WriteLine($"Failed to start debugger: {except}");

                // Both DebugEngine and Visual Studio already show error dialogs if DebugEngine
                // has to abort while it's attaching, no need to show another dialog in that case.
                if (except.ErrorCode != VSConstants.E_ABORT)
                {
                    _dialogUtil.ShowError(ErrorStrings.FailedToStartDebugger, except.ToString());
                }
            }
            finally
            {
                Close();
            }
        }