diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs index 973720aeb..c603f8054 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs @@ -1600,6 +1600,18 @@ internal class PluginInstallerWindow : Window, IDisposable ImGui.TextWrapped(Locs.PluginBody_Orphaned); ImGui.PopStyleColor(); } + else if (plugin is { IsDecommissioned: true } && !plugin.Manifest.IsThirdParty) + { + ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); + ImGui.TextWrapped(Locs.PluginBody_NoServiceOfficial); + ImGui.PopStyleColor(); + } + else if (plugin is { IsDecommissioned: true } && plugin.Manifest.IsThirdParty) + { + ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); + ImGui.TextWrapped(Locs.PluginBody_NoServiceThird); + ImGui.PopStyleColor(); + } else if (plugin != null && !plugin.CheckPolicy()) { ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); @@ -1978,6 +1990,13 @@ internal class PluginInstallerWindow : Window, IDisposable trouble = true; } + // Out of service + if (plugin.IsDecommissioned) + { + label += Locs.PluginTitleMod_NoService; + trouble = true; + } + // Scheduled for deletion if (plugin.Manifest.ScheduledForDeletion) { @@ -2875,6 +2894,8 @@ internal class PluginInstallerWindow : Window, IDisposable public static string PluginTitleMod_Disabled => Loc.Localize("InstallerDisabled", " (disabled)"); + public static string PluginTitleMod_NoService => Loc.Localize("InstallerNoService", " (decommissioned)"); + public static string PluginTitleMod_Unloaded => Loc.Localize("InstallerUnloaded", " (unloaded)"); public static string PluginTitleMod_HasUpdate => Loc.Localize("InstallerHasUpdate", " (has update)"); @@ -2943,6 +2964,10 @@ internal class PluginInstallerWindow : Window, IDisposable public static string PluginBody_Orphaned => Loc.Localize("InstallerOrphanedPluginBody ", "This plugin's source repository is no longer available. You may need to reinstall it from its repository, or re-add the repository."); + public static string PluginBody_NoServiceOfficial => Loc.Localize("InstallerNoServiceOfficialPluginBody", "This plugin is no longer being maintained. It will still work, but there will be no further updates and you can't reinstall it."); + + public static string PluginBody_NoServiceThird => Loc.Localize("InstallerNoServiceThirdPluginBody", "This plugin is no longer being serviced by its source repo. You may have to look for an updated version in another repo."); + public static string PluginBody_LoadFailed => Loc.Localize("InstallerLoadFailedPluginBody ", "This plugin failed to load. Please contact the author for more information."); public static string PluginBody_Banned => Loc.Localize("InstallerBannedPluginBody ", "This plugin was automatically disabled due to incompatibilities and is not available at the moment. Please wait for it to be updated by its author."); diff --git a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs index b49f5799c..807dd0bef 100644 --- a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs +++ b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs @@ -220,8 +220,13 @@ internal class LocalPlugin : IDisposable /// public bool IsOrphaned => !this.IsDev && !this.Manifest.InstalledFromUrl.IsNullOrEmpty() && // TODO(api8): Remove this, all plugins will have a proper flag - Service.Get().Repos.All(x => x.PluginMasterUrl != this.Manifest.InstalledFromUrl) && - this.Manifest.InstalledFromUrl != LocalPluginManifest.FlagMainRepo; + this.GetSourceRepository() == null; + + /// + /// Gets a value indicating whether or not this plugin is serviced(repo still exists, but plugin no longer does). + /// + public bool IsDecommissioned => !this.IsDev && + this.GetSourceRepository()?.PluginMaster?.FirstOrDefault(x => x.InternalName == this.Manifest.InternalName) == null; /// /// Gets a value indicating whether this plugin has been banned. @@ -638,6 +643,25 @@ internal class LocalPlugin : IDisposable } } + /// + /// Get the repository this plugin was installed from. + /// + /// The plugin repository this plugin was installed from, or null if it is no longer there or if the plugin is a dev plugin. + public PluginRepository? GetSourceRepository() + { + if (this.IsDev) + return null; + + var repos = Service.Get().Repos; + return repos.FirstOrDefault(x => + { + if (!x.IsThirdParty && !this.Manifest.IsThirdParty) + return true; + + return x.PluginMasterUrl == this.Manifest.InstalledFromUrl; + }); + } + private static void SetupLoaderConfig(LoaderConfig config) { config.IsUnloadable = true;