mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Add MinimumDalamudVersion to manifest, validate at install, update and load (#2248)
This commit is contained in:
commit
f5d93fb08e
7 changed files with 58 additions and 17 deletions
|
|
@ -20,7 +20,6 @@ public class FileDialogManager
|
||||||
/// <summary> Additional quick access items for the sidebar.</summary>
|
/// <summary> Additional quick access items for the sidebar.</summary>
|
||||||
public readonly List<(string Name, string Path, FontAwesomeIcon Icon, int Position)> CustomSideBarItems = [];
|
public readonly List<(string Name, string Path, FontAwesomeIcon Icon, int Position)> CustomSideBarItems = [];
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Additional flags with which to draw the window. </summary>
|
/// <summary> Additional flags with which to draw the window. </summary>
|
||||||
public ImGuiWindowFlags AddedWindowFlags = ImGuiWindowFlags.None;
|
public ImGuiWindowFlags AddedWindowFlags = ImGuiWindowFlags.None;
|
||||||
#pragma warning restore SA1401
|
#pragma warning restore SA1401
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
IsInstallableOutdated = 1 << 5,
|
IsInstallableOutdated = 1 << 5,
|
||||||
IsOrphan = 1 << 6,
|
IsOrphan = 1 << 6,
|
||||||
IsTesting = 1 << 7,
|
IsTesting = 1 << 7,
|
||||||
|
IsIncompatible = 1 << 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum InstalledPluginListFilter
|
private enum InstalledPluginListFilter
|
||||||
|
|
@ -2193,7 +2194,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, overlayAlpha);
|
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, overlayAlpha);
|
||||||
if (flags.HasFlag(PluginHeaderFlags.UpdateAvailable))
|
if (flags.HasFlag(PluginHeaderFlags.UpdateAvailable))
|
||||||
ImGui.Image(this.imageCache.UpdateIcon.ImGuiHandle, iconSize);
|
ImGui.Image(this.imageCache.UpdateIcon.ImGuiHandle, iconSize);
|
||||||
else if ((flags.HasFlag(PluginHeaderFlags.HasTrouble) && !pluginDisabled) || flags.HasFlag(PluginHeaderFlags.IsOrphan))
|
else if ((flags.HasFlag(PluginHeaderFlags.HasTrouble) && !pluginDisabled) || flags.HasFlag(PluginHeaderFlags.IsOrphan) || flags.HasFlag(PluginHeaderFlags.IsIncompatible))
|
||||||
ImGui.Image(this.imageCache.TroubleIcon.ImGuiHandle, iconSize);
|
ImGui.Image(this.imageCache.TroubleIcon.ImGuiHandle, iconSize);
|
||||||
else if (flags.HasFlag(PluginHeaderFlags.IsInstallableOutdated))
|
else if (flags.HasFlag(PluginHeaderFlags.IsInstallableOutdated))
|
||||||
ImGui.Image(this.imageCache.OutdatedInstallableIcon.ImGuiHandle, iconSize);
|
ImGui.Image(this.imageCache.OutdatedInstallableIcon.ImGuiHandle, iconSize);
|
||||||
|
|
@ -2269,9 +2270,14 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
ImGui.SetCursorPos(cursor);
|
ImGui.SetCursorPos(cursor);
|
||||||
|
|
||||||
// Outdated warning
|
// Outdated warning
|
||||||
if (plugin is { IsOutdated: true, IsBanned: false } || flags.HasFlag(PluginHeaderFlags.IsInstallableOutdated))
|
if (flags.HasFlag(PluginHeaderFlags.IsIncompatible))
|
||||||
{
|
{
|
||||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
||||||
|
ImGui.TextWrapped(Locs.PluginBody_Incompatible);
|
||||||
|
}
|
||||||
|
else if (plugin is { IsOutdated: true, IsBanned: false } || flags.HasFlag(PluginHeaderFlags.IsInstallableOutdated))
|
||||||
|
{
|
||||||
|
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
||||||
|
|
||||||
var bodyText = Locs.PluginBody_Outdated + " ";
|
var bodyText = Locs.PluginBody_Outdated + " ";
|
||||||
if (flags.HasFlag(PluginHeaderFlags.UpdateAvailable))
|
if (flags.HasFlag(PluginHeaderFlags.UpdateAvailable))
|
||||||
|
|
@ -2280,7 +2286,6 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
bodyText += Locs.PluginBody_Outdated_WaitForUpdate;
|
bodyText += Locs.PluginBody_Outdated_WaitForUpdate;
|
||||||
|
|
||||||
ImGui.TextWrapped(bodyText);
|
ImGui.TextWrapped(bodyText);
|
||||||
ImGui.PopStyleColor();
|
|
||||||
}
|
}
|
||||||
else if (plugin is { IsBanned: true })
|
else if (plugin is { IsBanned: true })
|
||||||
{
|
{
|
||||||
|
|
@ -2449,6 +2454,14 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
var effectiveApiLevel = useTesting && manifest.TestingDalamudApiLevel != null ? manifest.TestingDalamudApiLevel.Value : manifest.DalamudApiLevel;
|
var effectiveApiLevel = useTesting && manifest.TestingDalamudApiLevel != null ? manifest.TestingDalamudApiLevel.Value : manifest.DalamudApiLevel;
|
||||||
var isOutdated = effectiveApiLevel < PluginManager.DalamudApiLevel;
|
var isOutdated = effectiveApiLevel < PluginManager.DalamudApiLevel;
|
||||||
|
|
||||||
|
var isIncompatible = manifest.MinimumDalamudVersion != null &&
|
||||||
|
manifest.MinimumDalamudVersion > Util.AssemblyVersionParsed;
|
||||||
|
|
||||||
|
var enableInstallButton = this.updateStatus != OperationStatus.InProgress &&
|
||||||
|
this.installStatus != OperationStatus.InProgress &&
|
||||||
|
!isOutdated &&
|
||||||
|
!isIncompatible;
|
||||||
|
|
||||||
// Check for valid versions
|
// Check for valid versions
|
||||||
if ((useTesting && manifest.TestingAssemblyVersion == null) || manifest.AssemblyVersion == null)
|
if ((useTesting && manifest.TestingAssemblyVersion == null) || manifest.AssemblyVersion == null)
|
||||||
{
|
{
|
||||||
|
|
@ -2473,6 +2486,11 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
label += Locs.PluginTitleMod_TestingAvailable;
|
label += Locs.PluginTitleMod_TestingAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isIncompatible)
|
||||||
|
{
|
||||||
|
label += Locs.PluginTitleMod_Incompatible;
|
||||||
|
}
|
||||||
|
|
||||||
var isThirdParty = manifest.SourceRepo.IsThirdParty;
|
var isThirdParty = manifest.SourceRepo.IsThirdParty;
|
||||||
|
|
||||||
ImGui.PushID($"available{index}{manifest.InternalName}");
|
ImGui.PushID($"available{index}{manifest.InternalName}");
|
||||||
|
|
@ -2486,6 +2504,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
flags |= PluginHeaderFlags.IsInstallableOutdated;
|
flags |= PluginHeaderFlags.IsInstallableOutdated;
|
||||||
if (useTesting || manifest.IsTestingExclusive)
|
if (useTesting || manifest.IsTestingExclusive)
|
||||||
flags |= PluginHeaderFlags.IsTesting;
|
flags |= PluginHeaderFlags.IsTesting;
|
||||||
|
if (isIncompatible)
|
||||||
|
flags |= PluginHeaderFlags.IsIncompatible;
|
||||||
|
|
||||||
if (this.DrawPluginCollapsingHeader(label, null, manifest, flags, () => this.DrawAvailablePluginContextMenu(manifest), index))
|
if (this.DrawPluginCollapsingHeader(label, null, manifest, flags, () => this.DrawAvailablePluginContextMenu(manifest), index))
|
||||||
{
|
{
|
||||||
|
|
@ -2513,9 +2533,6 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
|
|
||||||
// Controls
|
|
||||||
var disabled = this.updateStatus == OperationStatus.InProgress || this.installStatus == OperationStatus.InProgress || isOutdated;
|
|
||||||
|
|
||||||
var versionString = useTesting
|
var versionString = useTesting
|
||||||
? $"{manifest.TestingAssemblyVersion}"
|
? $"{manifest.TestingAssemblyVersion}"
|
||||||
: $"{manifest.AssemblyVersion}";
|
: $"{manifest.AssemblyVersion}";
|
||||||
|
|
@ -2524,7 +2541,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
{
|
{
|
||||||
ImGuiComponents.DisabledButton(Locs.PluginButton_SafeMode);
|
ImGuiComponents.DisabledButton(Locs.PluginButton_SafeMode);
|
||||||
}
|
}
|
||||||
else if (disabled)
|
else if (!enableInstallButton)
|
||||||
{
|
{
|
||||||
ImGuiComponents.DisabledButton(Locs.PluginButton_InstallVersion(versionString));
|
ImGuiComponents.DisabledButton(Locs.PluginButton_InstallVersion(versionString));
|
||||||
}
|
}
|
||||||
|
|
@ -4105,6 +4122,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
|
|
||||||
public static string PluginTitleMod_TestingAvailable => Loc.Localize("InstallerTestingAvailable", " (has testing version)");
|
public static string PluginTitleMod_TestingAvailable => Loc.Localize("InstallerTestingAvailable", " (has testing version)");
|
||||||
|
|
||||||
|
public static string PluginTitleMod_Incompatible => Loc.Localize("InstallerTitleModIncompatible", " (incompatible)");
|
||||||
|
|
||||||
public static string PluginTitleMod_DevPlugin => Loc.Localize("InstallerDevPlugin", " (dev plugin)");
|
public static string PluginTitleMod_DevPlugin => Loc.Localize("InstallerDevPlugin", " (dev plugin)");
|
||||||
|
|
||||||
public static string PluginTitleMod_UpdateFailed => Loc.Localize("InstallerUpdateFailed", " (update failed)");
|
public static string PluginTitleMod_UpdateFailed => Loc.Localize("InstallerUpdateFailed", " (update failed)");
|
||||||
|
|
@ -4161,6 +4180,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
|
|
||||||
public static string PluginBody_Outdated => Loc.Localize("InstallerOutdatedPluginBody ", "This plugin is outdated and incompatible.");
|
public static string PluginBody_Outdated => Loc.Localize("InstallerOutdatedPluginBody ", "This plugin is outdated and incompatible.");
|
||||||
|
|
||||||
|
public static string PluginBody_Incompatible => Loc.Localize("InstallerIncompatiblePluginBody ", "This plugin is incompatible with your version of Dalamud. Please attempt to restart your game.");
|
||||||
|
|
||||||
public static string PluginBody_Outdated_WaitForUpdate => Loc.Localize("InstallerOutdatedWaitForUpdate", "Please wait for it to be updated by its author.");
|
public static string PluginBody_Outdated_WaitForUpdate => Loc.Localize("InstallerOutdatedWaitForUpdate", "Please wait for it to be updated by its author.");
|
||||||
|
|
||||||
public static string PluginBody_Outdated_CanNowUpdate => Loc.Localize("InstallerOutdatedCanNowUpdate", "An update is available for installation.");
|
public static string PluginBody_Outdated_CanNowUpdate => Loc.Localize("InstallerOutdatedCanNowUpdate", "An update is available for installation.");
|
||||||
|
|
|
||||||
|
|
@ -1760,6 +1760,7 @@ internal class PluginManager : IInternalDisposableService
|
||||||
var updates = this.AvailablePlugins
|
var updates = this.AvailablePlugins
|
||||||
.Where(remoteManifest => plugin.Manifest.InternalName == remoteManifest.InternalName)
|
.Where(remoteManifest => plugin.Manifest.InternalName == remoteManifest.InternalName)
|
||||||
.Where(remoteManifest => plugin.Manifest.InstalledFromUrl == remoteManifest.SourceRepo.PluginMasterUrl || !remoteManifest.SourceRepo.IsThirdParty)
|
.Where(remoteManifest => plugin.Manifest.InstalledFromUrl == remoteManifest.SourceRepo.PluginMasterUrl || !remoteManifest.SourceRepo.IsThirdParty)
|
||||||
|
.Where(remoteManifest => remoteManifest.MinimumDalamudVersion == null || Util.AssemblyVersionParsed >= remoteManifest.MinimumDalamudVersion)
|
||||||
.Where(remoteManifest =>
|
.Where(remoteManifest =>
|
||||||
{
|
{
|
||||||
var useTesting = this.UseTesting(remoteManifest);
|
var useTesting = this.UseTesting(remoteManifest);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ using Dalamud.Plugin.Internal.Exceptions;
|
||||||
using Dalamud.Plugin.Internal.Loader;
|
using Dalamud.Plugin.Internal.Loader;
|
||||||
using Dalamud.Plugin.Internal.Profiles;
|
using Dalamud.Plugin.Internal.Profiles;
|
||||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||||
|
using Dalamud.Utility;
|
||||||
|
|
||||||
namespace Dalamud.Plugin.Internal.Types;
|
namespace Dalamud.Plugin.Internal.Types;
|
||||||
|
|
||||||
|
|
@ -313,6 +314,9 @@ internal class LocalPlugin : IAsyncDisposable
|
||||||
if (!this.CheckPolicy())
|
if (!this.CheckPolicy())
|
||||||
throw new PluginPreconditionFailedException($"Unable to load {this.Name} as a load policy forbids it");
|
throw new PluginPreconditionFailedException($"Unable to load {this.Name} as a load policy forbids it");
|
||||||
|
|
||||||
|
if (this.Manifest.MinimumDalamudVersion != null && this.Manifest.MinimumDalamudVersion > Util.AssemblyVersionParsed)
|
||||||
|
throw new PluginPreconditionFailedException($"Unable to load {this.Name}, Dalamud version is lower than minimum required version {this.Manifest.MinimumDalamudVersion}");
|
||||||
|
|
||||||
this.State = PluginState.Loading;
|
this.State = PluginState.Loading;
|
||||||
Log.Information($"Loading {this.DllFile.Name}");
|
Log.Information($"Loading {this.DllFile.Name}");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public interface IPluginManifest
|
||||||
/// Gets the public name of the plugin.
|
/// Gets the public name of the plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a punchline of the plugins functions.
|
/// Gets a punchline of the plugins functions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -26,7 +26,7 @@ public interface IPluginManifest
|
||||||
/// Gets the author/s of the plugin.
|
/// Gets the author/s of the plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Author { get; }
|
public string Author { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the plugin can be unloaded asynchronously.
|
/// Gets a value indicating whether the plugin can be unloaded asynchronously.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -41,17 +41,22 @@ public interface IPluginManifest
|
||||||
/// Gets the assembly version of the plugin's testing variant.
|
/// Gets the assembly version of the plugin's testing variant.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Version? TestingAssemblyVersion { get; }
|
public Version? TestingAssemblyVersion { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the minimum Dalamud assembly version this plugin requires.
|
||||||
|
/// </summary>
|
||||||
|
public Version? MinimumDalamudVersion { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the DIP17 channel name.
|
/// Gets the DIP17 channel name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Dip17Channel { get; }
|
public string? Dip17Channel { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the last time this plugin was updated.
|
/// Gets the last time this plugin was updated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long LastUpdate { get; }
|
public long LastUpdate { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a changelog, null if none exists.
|
/// Gets a changelog, null if none exists.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -88,7 +93,7 @@ public interface IPluginManifest
|
||||||
/// Gets an URL to the website or source code of the plugin.
|
/// Gets an URL to the website or source code of the plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? RepoUrl { get; }
|
public string? RepoUrl { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a description of the plugins functions.
|
/// Gets a description of the plugins functions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,10 @@ internal record PluginManifest : IPluginManifest
|
||||||
[JsonConverter(typeof(GameVersionConverter))]
|
[JsonConverter(typeof(GameVersionConverter))]
|
||||||
public GameVersion? ApplicableVersion { get; init; } = GameVersion.Any;
|
public GameVersion? ApplicableVersion { get; init; } = GameVersion.Any;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
[JsonProperty]
|
||||||
|
public Version? MinimumDalamudVersion { get; init; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public int DalamudApiLevel { get; init; } = PluginManager.DalamudApiLevel;
|
public int DalamudApiLevel { get; init; } = PluginManager.DalamudApiLevel;
|
||||||
|
|
|
||||||
|
|
@ -70,10 +70,17 @@ public static class Util
|
||||||
private static ulong moduleEndAddr;
|
private static ulong moduleEndAddr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the assembly version of Dalamud.
|
/// Gets the Dalamud version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Api13ToDo("Remove. Make both versions here internal. Add an API somewhere.")]
|
||||||
public static string AssemblyVersion { get; } =
|
public static string AssemblyVersion { get; } =
|
||||||
Assembly.GetAssembly(typeof(ChatHandlers)).GetName().Version.ToString();
|
Assembly.GetAssembly(typeof(ChatHandlers))!.GetName().Version!.ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Dalamud version.
|
||||||
|
/// </summary>
|
||||||
|
internal static Version AssemblyVersionParsed { get; } =
|
||||||
|
Assembly.GetAssembly(typeof(ChatHandlers))!.GetName().Version!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the SCM Version from the assembly, or null if it cannot be found. This method will generally return
|
/// Gets the SCM Version from the assembly, or null if it cannot be found. This method will generally return
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue