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);
        }
Example #2
0
        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));
            });
        }
Example #3
0
        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);
        }