public MonoInstallTrigger(Lifetime lifetime, ILogger logger, ISolutionLoadTasksScheduler scheduler, ISolution solution, UnitySolutionTracker unitySolutionTracker, UnityHost host, NotificationsModel notificationsModel) { if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Windows) { return; } scheduler.EnqueueTask(new SolutionLoadTask("Check mono runtime", SolutionLoadTaskKinds.AfterDone, () => { if (!unitySolutionTracker.IsUnityGeneratedProject.Value) { return; } if (!HasModernUnityProjects(solution)) { return; } solution.Locks.Tasks.Queue(lifetime, () => { var wellKnownMonoRuntimes = MonoRuntimeDetector.DetectWellKnownMonoRuntimes(); var installedValidMono = wellKnownMonoRuntimes .Any(runtime => { var parsedVersion = string.Empty; try { parsedVersion = ProcessOutputUtil.ExtractMonoVersion(runtime.ExePath); } catch (Exception e) { logger.Warn(e); } // if we fail to parse version - consider it is old if (Version.TryParse(parsedVersion, out var version)) { return(version >= new Version(5, 16)); // mono 5.16+ supports C# 7.3 } logger.Warn("Failed to parse ProcessOutputUtil.ExtractMonoVersion output."); return(false); }); if (installedValidMono) { return; } if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.MacOsX) { solution.Locks.ExecuteOrQueue(lifetime, "Show install mono dialog", () => { host.PerformModelAction(model => model.ShowInstallMonoDialog()); }); } else if (PlatformUtil.RuntimePlatform == PlatformUtil.Platform.Linux) { var notification = new NotificationModel("Mono 5.16+ is required", "<html>Project requires new Mono with MSBuild for new C# language features support.<br>" + RiderContextNotificationHelper.MakeOpenSettingsLink( WellKnownSettingPages.Environment, "Install the latest Mono") + ".<br>" + "If a Mono runtime is available in a non-standard location, please " + RiderContextNotificationHelper.MakeOpenSettingsLink( WellKnownSettingPages.ToolsetAndBuild, "specify the custom runtime location in settings") + ".</html>" , true, RdNotificationEntryType.WARN); solution.Locks.ExecuteOrQueue(lifetime, "MonoInstallTrigger.Notify", () => notificationsModel.Notification(notification)); } }); })); }
public UnrealPluginDetector(Lifetime lifetime, ILogger logger, CppUE4SolutionDetector solutionDetector, ISolution solution, IShellLocks locks, ISolutionLoadTasksScheduler scheduler) { myLifetime = lifetime; InstallInfoProperty = new Property <UnrealPluginInstallInfo>(myLifetime, "UnrealPlugin.InstallInfoNotification", null, true); myLogger = logger; mySolution = solution; mySolutionDetector = solutionDetector; mySolutionDetector.IsUE4Solution_Observable.Change.Advise_When(myLifetime, newValue => newValue == TriBool.True, _ => { scheduler.EnqueueTask(new SolutionLoadTask("Find installed RiderLink plugins", SolutionLoadTaskKinds.Done, () => { myLogger.Info("[UnrealLink]: Looking for RiderLink plugins"); myUnrealVersion = mySolutionDetector.Version; if (myUnrealVersion < myMinimalSupportedVersion) { locks.ExecuteOrQueue(myLifetime, "UnrealLink.CheckSupportedVersion", () => { var notification = new NotificationModel( $"Unreal Engine {myMinimalSupportedVersion}+ is required", $"<html>UnrealLink supports Unreal Engine versions starting with {myMinimalSupportedVersion}<br>" + "<b>WARNING: Advanced users only</b><br>" + "You can manually download the latest version of plugin and build It for your version of Unreal Editor<br>" + RiderContextNotificationHelper.MakeLink( "https://github.com/JetBrains/UnrealLink/releases/latest", "Download latest Unreal Editor plugin") + "</html>", true, RdNotificationEntryType.WARN, new List <NotificationHyperlink>()); var notificationsModel = Shell.Instance.GetComponent <NotificationsModel>(); notificationsModel.Notification(notification); }); return; } var installInfo = new UnrealPluginInstallInfo(); var foundEnginePlugin = TryGetEnginePluginFromSolution(solutionDetector, installInfo); ISet <FileSystemPath> uprojectLocations; using (solution.Locks.UsingReadLock()) { var allProjects = mySolution.GetAllProjects(); if (solutionDetector.SupportRiderProjectModel == CppUE4ProjectModelSupportMode.UprojectOpened) { uprojectLocations = allProjects.Where(project => { if (project.IsMiscProjectItem() || project.IsMiscFilesProject()) { return(false); } var location = project.Location; if (location == null) { return(false); } if (EXCLUDED_PROJECTS.Contains(location.NameWithoutExtension)) { return(false); } // TODO: drop this ugly check after updating to net211 where Location == "path/to/game.uproject" var isUproject = location.ExistsFile && location.ExtensionNoDot == UPROJECT_FILE_FORMAT && location.NameWithoutExtension == project.Name; return(isUproject || (location / $"{location.Name}.uproject").ExistsFile); }).Select(project => { var location = project.Location; if (location.ExistsFile) { return(location); } return(location / $"{location.Name}.uproject"); }).ToSet(); } else { uprojectLocations = allProjects.SelectMany(project => project.GetAllProjectFiles(projectFile => { var location = projectFile.Location; if (location == null || !location.ExistsFile) { return(false); } return(location.ExtensionNoDot == UPROJECT_FILE_FORMAT && location.NameWithoutExtension == project.Name); })).Select(file => file.Location).ToSet(); } } myLogger.Info($"[UnrealLink]: Found {uprojectLocations.Count} uprojects"); if (!foundEnginePlugin && !uprojectLocations.IsEmpty()) { // All projects in the solution are bound to the same engine // So take first project and use it to find Unreal Engine TryGetEnginePluginFromUproject(uprojectLocations.FirstNotNull(), installInfo); foundEnginePlugin = installInfo.EnginePlugin.IsPluginAvailable; } // Gather data about Project plugins foreach (var uprojectLocation in uprojectLocations) { myLogger.Info($"[UnrealLink]: Looking for plugin in {uprojectLocation}"); var projectPlugin = GetProjectPluginForUproject(uprojectLocation); if (projectPlugin.IsPluginAvailable) { myLogger.Info( $"[UnrealLink]: found plugin {projectPlugin.UnrealPluginRootFolder}"); } installInfo.ProjectPlugins.Add(projectPlugin); } if (foundEnginePlugin) { installInfo.Location = PluginInstallLocation.Engine; } else if (installInfo.ProjectPlugins.Any(description => description.IsPluginAvailable)) { installInfo.Location = PluginInstallLocation.Game; } else { installInfo.Location = PluginInstallLocation.NotInstalled; } InstallInfoProperty.SetValue(installInfo); })); }); }