private static UnrealPluginInstallInfo.InstallDescription GetPluginInfo( [NotNull] FileSystemPath upluginFilePath, [CanBeNull] FileSystemPath uprojectFilePath = null) { var installDescription = new UnrealPluginInstallInfo.InstallDescription() { UnrealPluginRootFolder = upluginFilePath.Directory, UprojectFilePath = uprojectFilePath != null ? uprojectFilePath : FileSystemPath.Empty }; if (!upluginFilePath.ExistsFile) { return(installDescription); } var version = PluginPathsProvider.GetPluginVersion(upluginFilePath); if (version == null) { return(installDescription); } installDescription.IsPluginAvailable = true; installDescription.PluginVersion = version; return(installDescription); }
public static void RefreshProjects(Lifetime parentLifetime, [NotNull] ISolution solution, [CanBeNull] UnrealPluginInstallInfo.InstallDescription installDescription, [CanBeNull] VirtualFileSystemPath engineRoot) { parentLifetime.UsingNestedAsync(async lt => { var lifetimeDefinition = lt.CreateNested(); var lifetime = lifetimeDefinition.Lifetime; var unrealHost = solution.GetComponent <UnrealHost>(); lifetime.Bracket( () => unrealHost.myModel.RefreshInProgress.Value = true, () => unrealHost.myModel.RefreshInProgress.Value = false ); var task = RiderBackgroundTaskBuilder.Create() .AsCancelable(() => { unrealHost.myModel.RiderLinkInstallMessage( new InstallMessage("RiderLink projects refresh has been cancelled", ContentType.Error)); lifetimeDefinition.Terminate(); }) .WithHeader("Refreshing project model"); var backgroundTaskHost = solution.GetComponent <RiderBackgroundTaskHost>(); backgroundTaskHost.AddNewTask(lifetime, task); var uprojectFile = installDescription?.UprojectPath; if (uprojectFile.IsNullOrEmpty()) { var cppUe4SolutionDetector = solution.GetComponent <CppUE4SolutionDetector>(); using (solution.Locks.UsingReadLock()) { uprojectFile = cppUe4SolutionDetector.GetUProjectPath(); } } await lifetime.StartBackground(() => RegenerateProjectFiles(lifetime, solution, unrealHost, engineRoot, uprojectFile)); }); }
private async Task <bool> InstallPlugin(Lifetime lifetime, UnrealPluginInstallInfo.InstallDescription installDescription, FileSystemPath uprojectFile, IProperty <double> progressProperty, double range) { using var def = new LifetimeDefinition(); var ZIP_STEP = 0.1 * range; var PATCH_STEP = 0.1 * range; var BUILD_STEP = 0.6 * range; var REFRESH_STEP = 0.1 * range; var pluginRootFolder = installDescription.UnrealPluginRootFolder; var editorPluginPathFile = myPathsProvider.PathToPackedPlugin; var pluginTmpDir = FileSystemDefinition.CreateTemporaryDirectory(null, TMP_PREFIX); def.Lifetime.OnTermination(() => { pluginTmpDir.Delete(); }); try { ZipFile.ExtractToDirectory(editorPluginPathFile.FullPath, pluginTmpDir.FullPath); progressProperty.Value += ZIP_STEP; } catch (Exception exception) { myLogger.Warn(exception, $"[UnrealLink]: Couldn't extract {editorPluginPathFile} to {pluginTmpDir}"); const string unzipFailTitle = "Failed to unzip new RiderLink plugin"; var unzipFailText = $"Failed to unzip new version of RiderLink ({editorPluginPathFile.FullPath}) to user folder ({pluginTmpDir.FullPath})\n" + "Try restarting Rider in administrative mode"; myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(unzipFailTitle, ContentType.Error)); myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(unzipFailText, ContentType.Error)); return(false); } lifetime.ToCancellationToken().ThrowIfCancellationRequested(); var upluginFile = UnrealPluginDetector.GetPathToUpluginFile(pluginTmpDir); var pluginBuildOutput = FileSystemDefinition.CreateTemporaryDirectory(null, TMP_PREFIX); def.Lifetime.OnTermination(() => { pluginBuildOutput.Delete(); }); var buildProgress = progressProperty.Value; var isPluginBuilt = await BuildPlugin(lifetime, upluginFile, pluginBuildOutput, uprojectFile, value => progressProperty.SetValue(buildProgress + value *BUILD_STEP)); if (!isPluginBuilt) { myLogger.Warn($"Failed to build RiderLink for any available project"); const string failedBuildText = "Failed to build RiderLink plugin"; myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(failedBuildText, ContentType.Error)); return(false); } progressProperty.Value = buildProgress + BUILD_STEP; lifetime.ToCancellationToken().ThrowIfCancellationRequested(); if (!PatchUpluginFileAfterInstallation(pluginBuildOutput)) { const string failedToPatch = "Failed to patch RiderLink.uplugin"; var failedPatchText = "Failed to set `EnableByDefault` to true in RiderLink.uplugin\n" + "You need to manually enable RiderLink in UnrealEditor"; myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(failedToPatch, ContentType.Normal)); myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(failedPatchText, ContentType.Normal)); } progressProperty.Value += PATCH_STEP; lifetime.ToCancellationToken().ThrowIfCancellationRequested(); pluginRootFolder.CreateDirectory().DeleteChildren(); pluginBuildOutput.Copy(pluginRootFolder); progressProperty.Value += REFRESH_STEP; installDescription.IsPluginAvailable = true; installDescription.PluginVersion = myPathsProvider.CurrentPluginVersion; const string title = "RiderLink plugin installed"; var text = $"RiderLink plugin was installed to: {pluginRootFolder}"; myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(title, ContentType.Normal)); myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(text, ContentType.Normal)); var notification = new NotificationModel(title, text, true, RdNotificationEntryType.INFO, new List <NotificationHyperlink>()); mySolution.Locks.ExecuteOrQueue(Lifetime, "UnrealLink.InstallPlugin", () => { myNotificationsModel.Notification(notification); }); mySolution.Locks.ExecuteOrQueueReadLock(Lifetime, "UnrealLink.RegenerateProjectFiles", () => { var cppUe4SolutionDetector = mySolution.GetComponent <CppUE4SolutionDetector>(); if (cppUe4SolutionDetector.SupportRiderProjectModel != CppUE4ProjectModelSupportMode.UprojectOpened) { RegenerateProjectFiles(uprojectFile); } }); return(true); }