diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d780df2fc..e8c521195 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -29,6 +29,12 @@ jobs:
run: .\build.ps1 compile
- name: Test Dalamud
run: .\build.ps1 test
+ - name: Sign Dalamud
+ if: ${{ github.repository_owner == 'goatcorp' }}
+ env:
+ CODESIGN_CERT_PFX: ${{ secrets.CODESIGN_CERT_PFX }}
+ CODESIGN_CERT_PASSWORD: ${{ secrets.CODESIGN_CERT_PASSWORD }}
+ run: .\sign.ps1 .\bin\Release
- name: Create hashlist
run: .\CreateHashList.ps1 .\bin\Release
- name: Upload artifact
diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs
index 19b4f841c..1975505a8 100644
--- a/Dalamud/EntryPoint.cs
+++ b/Dalamud/EntryPoint.cs
@@ -263,7 +263,7 @@ public sealed class EntryPoint
{
pluginInfo = $"Plugin that caused this:\n{plugin.Name}\n\nClick \"Yes\" and remove it.\n\n";
- if (plugin.Manifest.IsThirdParty)
+ if (plugin.IsThirdParty)
supportText = string.Empty;
}
}
diff --git a/Dalamud/Interface/Internal/Windows/PluginImageCache.cs b/Dalamud/Interface/Internal/Windows/PluginImageCache.cs
index 0aeb0722d..766f80b23 100644
--- a/Dalamud/Interface/Internal/Windows/PluginImageCache.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginImageCache.cs
@@ -11,6 +11,7 @@ using Dalamud.Game;
using Dalamud.Networking.Http;
using Dalamud.Plugin.Internal;
using Dalamud.Plugin.Internal.Types;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Dalamud.Utility;
using ImGuiScene;
using Serilog;
@@ -232,7 +233,7 @@ internal class PluginImageCache : IDisposable, IServiceType
/// If the plugin was third party sourced.
/// Cached image textures, or an empty array.
/// True if an entry exists, may be null if currently downloading.
- public bool TryGetIcon(LocalPlugin? plugin, PluginManifest manifest, bool isThirdParty, out TextureWrap? iconTexture)
+ public bool TryGetIcon(LocalPlugin? plugin, IPluginManifest manifest, bool isThirdParty, out TextureWrap? iconTexture)
{
iconTexture = null;
@@ -274,7 +275,7 @@ internal class PluginImageCache : IDisposable, IServiceType
/// If the plugin was third party sourced.
/// Cached image textures, or an empty array.
/// True if the image array exists, may be empty if currently downloading.
- public bool TryGetImages(LocalPlugin? plugin, PluginManifest manifest, bool isThirdParty, out TextureWrap?[] imageTextures)
+ public bool TryGetImages(LocalPlugin? plugin, IPluginManifest manifest, bool isThirdParty, out TextureWrap?[] imageTextures)
{
if (!this.pluginImagesMap.TryAdd(manifest.InternalName, null))
{
@@ -307,7 +308,7 @@ internal class PluginImageCache : IDisposable, IServiceType
byte[]? bytes,
string name,
string? loc,
- PluginManifest manifest,
+ IPluginManifest manifest,
int maxWidth,
int maxHeight,
bool requireSquare)
@@ -491,7 +492,7 @@ internal class PluginImageCache : IDisposable, IServiceType
Log.Debug("Plugin image loader has shutdown");
}
- private async Task DownloadPluginIconAsync(LocalPlugin? plugin, PluginManifest manifest, bool isThirdParty, ulong requestedFrame)
+ private async Task DownloadPluginIconAsync(LocalPlugin? plugin, IPluginManifest manifest, bool isThirdParty, ulong requestedFrame)
{
if (plugin is { IsDev: true })
{
@@ -558,7 +559,7 @@ internal class PluginImageCache : IDisposable, IServiceType
return icon;
}
- private async Task DownloadPluginImagesAsync(TextureWrap?[] pluginImages, LocalPlugin? plugin, PluginManifest manifest, bool isThirdParty, ulong requestedFrame)
+ private async Task DownloadPluginImagesAsync(TextureWrap?[] pluginImages, LocalPlugin? plugin, IPluginManifest manifest, bool isThirdParty, ulong requestedFrame)
{
if (plugin is { IsDev: true })
{
@@ -671,18 +672,15 @@ internal class PluginImageCache : IDisposable, IServiceType
}
}
- private string? GetPluginIconUrl(PluginManifest manifest, bool isThirdParty, bool isTesting)
+ private string? GetPluginIconUrl(IPluginManifest manifest, bool isThirdParty, bool isTesting)
{
if (isThirdParty)
return manifest.IconUrl;
- if (manifest.IsDip17Plugin)
- return MainRepoDip17ImageUrl.Format(manifest.Dip17Channel!, manifest.InternalName, "icon.png");
-
- return MainRepoImageUrl.Format(isTesting ? "testing" : "plugins", manifest.InternalName, "icon.png");
+ return MainRepoDip17ImageUrl.Format(manifest.Dip17Channel!, manifest.InternalName, "icon.png");
}
- private List? GetPluginImageUrls(PluginManifest manifest, bool isThirdParty, bool isTesting)
+ private List? GetPluginImageUrls(IPluginManifest manifest, bool isThirdParty, bool isTesting)
{
if (isThirdParty)
{
@@ -698,14 +696,7 @@ internal class PluginImageCache : IDisposable, IServiceType
var output = new List();
for (var i = 1; i <= 5; i++)
{
- if (manifest.IsDip17Plugin)
- {
- output.Add(MainRepoDip17ImageUrl.Format(manifest.Dip17Channel!, manifest.InternalName, $"image{i}.png"));
- }
- else
- {
- output.Add(MainRepoImageUrl.Format(isTesting ? "testing" : "plugins", manifest.InternalName, $"image{i}.png"));
- }
+ output.Add(MainRepoDip17ImageUrl.Format(manifest.Dip17Channel!, manifest.InternalName, $"image{i}.png"));
}
return output;
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs
index 2dc182e9a..984732509 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/DalamudChangelogManager.cs
@@ -48,15 +48,12 @@ internal class DalamudChangelogManager
foreach (var plugin in this.manager.InstalledPlugins)
{
- if (!plugin.Manifest.IsThirdParty)
+ if (!plugin.IsThirdParty)
{
- if (!plugin.Manifest.IsDip17Plugin)
- continue;
-
var pluginChangelogs = await client.GetFromJsonAsync(string.Format(
- PluginChangelogUrl,
- plugin.Manifest.InternalName,
- plugin.Manifest.Dip17Channel));
+ PluginChangelogUrl,
+ plugin.Manifest.InternalName,
+ plugin.Manifest.Dip17Channel));
changelogs = changelogs.Concat(pluginChangelogs.Versions
.Where(x => x.Dip17Track == plugin.Manifest.Dip17Channel)
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginChangelogEntry.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginChangelogEntry.cs
index 247e2d353..b4048536e 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginChangelogEntry.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginChangelogEntry.cs
@@ -33,7 +33,7 @@ internal class PluginChangelogEntry : IChangelogEntry
{
this.Plugin = plugin;
- this.Version = plugin.Manifest.EffectiveVersion.ToString();
+ this.Version = plugin.EffectiveVersion.ToString();
this.Text = plugin.Manifest.Changelog ?? Loc.Localize("ChangelogNoText", "No changelog for this version.");
this.Author = plugin.Manifest.Author;
this.Date = DateTimeOffset.FromUnixTimeSeconds(this.Plugin.Manifest.LastUpdate).DateTime;
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
index ba249e051..05376a770 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
@@ -24,6 +24,7 @@ using Dalamud.Plugin.Internal;
using Dalamud.Plugin.Internal.Exceptions;
using Dalamud.Plugin.Internal.Profiles;
using Dalamud.Plugin.Internal.Types;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Dalamud.Support;
using Dalamud.Utility;
using ImGuiNET;
@@ -88,7 +89,7 @@ internal class PluginInstallerWindow : Window, IDisposable
private string feedbackModalBody = string.Empty;
private string feedbackModalContact = string.Empty;
private bool feedbackModalIncludeException = false;
- private PluginManifest? feedbackPlugin = null;
+ private IPluginManifest? feedbackPlugin = null;
private bool feedbackIsTesting = false;
private int updatePluginCount = 0;
@@ -1606,7 +1607,7 @@ internal class PluginInstallerWindow : Window, IDisposable
return ready;
}
- private bool DrawPluginCollapsingHeader(string label, LocalPlugin? plugin, PluginManifest manifest, bool isThirdParty, bool trouble, bool updateAvailable, bool isNew, bool installableOutdated, bool isOrphan, Action drawContextMenuAction, int index)
+ private bool DrawPluginCollapsingHeader(string label, LocalPlugin? plugin, IPluginManifest manifest, bool isThirdParty, bool trouble, bool updateAvailable, bool isNew, bool installableOutdated, bool isOrphan, Action drawContextMenuAction, int index)
{
ImGui.Separator();
@@ -1741,13 +1742,13 @@ internal class PluginInstallerWindow : Window, IDisposable
ImGui.TextWrapped(Locs.PluginBody_Orphaned);
ImGui.PopStyleColor();
}
- else if (plugin is { IsDecommissioned: true } && !plugin.Manifest.IsThirdParty)
+ else if (plugin is { IsDecommissioned: true, IsThirdParty: false })
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGui.TextWrapped(Locs.PluginBody_NoServiceOfficial);
ImGui.PopStyleColor();
}
- else if (plugin is { IsDecommissioned: true } && plugin.Manifest.IsThirdParty)
+ else if (plugin is { IsDecommissioned: true, IsThirdParty: true })
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGui.TextWrapped(Locs.PluginBody_NoServiceThird);
@@ -1808,7 +1809,7 @@ internal class PluginInstallerWindow : Window, IDisposable
if (log is PluginChangelogEntry pluginLog)
{
icon = this.imageCache.DefaultIcon;
- var hasIcon = this.imageCache.TryGetIcon(pluginLog.Plugin, pluginLog.Plugin.Manifest, pluginLog.Plugin.Manifest.IsThirdParty, out var cachedIconTex);
+ var hasIcon = this.imageCache.TryGetIcon(pluginLog.Plugin, pluginLog.Plugin.Manifest, pluginLog.Plugin.IsThirdParty, out var cachedIconTex);
if (hasIcon && cachedIconTex != null)
{
icon = cachedIconTex;
@@ -2031,12 +2032,14 @@ internal class PluginInstallerWindow : Window, IDisposable
}
// Testing
- if (plugin.Manifest.Testing)
+ if (plugin.IsTesting)
{
label += Locs.PluginTitleMod_TestingVersion;
}
- if (plugin.Manifest.IsAvailableForTesting && configuration.DoPluginTest && testingOptIn == null)
+ var hasTestingAvailable = this.pluginListAvailable.Any(x => x.InternalName == plugin.InternalName &&
+ x.IsAvailableForTesting);
+ if (hasTestingAvailable && configuration.DoPluginTest && testingOptIn == null)
{
label += Locs.PluginTitleMod_TestingAvailable;
}
@@ -2132,7 +2135,7 @@ internal class PluginInstallerWindow : Window, IDisposable
ImGui.PushID($"installed{index}{plugin.Manifest.InternalName}");
var hasChangelog = !plugin.Manifest.Changelog.IsNullOrEmpty();
- if (this.DrawPluginCollapsingHeader(label, plugin, plugin.Manifest, plugin.Manifest.IsThirdParty, trouble, availablePluginUpdate != default, false, false, plugin.IsOrphaned, () => this.DrawInstalledPluginContextMenu(plugin, testingOptIn), index))
+ if (this.DrawPluginCollapsingHeader(label, plugin, plugin.Manifest, plugin.IsThirdParty, trouble, availablePluginUpdate != default, false, false, plugin.IsOrphaned, () => this.DrawInstalledPluginContextMenu(plugin, testingOptIn), index))
{
if (!this.WasPluginSeen(plugin.Manifest.InternalName))
configuration.SeenPluginInternalName.Add(plugin.Manifest.InternalName);
@@ -2154,12 +2157,15 @@ internal class PluginInstallerWindow : Window, IDisposable
ImGui.SameLine();
ImGui.TextColored(ImGuiColors.DalamudGrey3, downloadText);
- var isThirdParty = manifest.IsThirdParty;
+ var acceptsFeedback =
+ this.pluginListAvailable.Any(x => x.InternalName == plugin.InternalName && x.AcceptsFeedback);
+
+ var isThirdParty = plugin.IsThirdParty;
var canFeedback = !isThirdParty &&
!plugin.IsDev &&
!plugin.IsOrphaned &&
plugin.Manifest.DalamudApiLevel == PluginManager.DalamudApiLevel &&
- plugin.Manifest.AcceptsFeedback &&
+ acceptsFeedback &&
availablePluginUpdate == default;
// Installed from
@@ -2215,7 +2221,7 @@ internal class PluginInstallerWindow : Window, IDisposable
this.DrawUpdateSinglePluginButton(availablePluginUpdate);
ImGui.SameLine();
- ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{plugin.Manifest.EffectiveVersion}");
+ ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{plugin.EffectiveVersion}");
ImGuiHelpers.ScaledDummy(5);
@@ -2226,7 +2232,7 @@ internal class PluginInstallerWindow : Window, IDisposable
if (hasChangelog)
{
- if (ImGui.TreeNode(Locs.PluginBody_CurrentChangeLog(plugin.Manifest.EffectiveVersion)))
+ if (ImGui.TreeNode(Locs.PluginBody_CurrentChangeLog(plugin.EffectiveVersion)))
{
this.DrawInstalledPluginChangelog(plugin.Manifest);
ImGui.TreePop();
@@ -2252,7 +2258,7 @@ internal class PluginInstallerWindow : Window, IDisposable
ImGui.PopID();
}
- private void DrawInstalledPluginChangelog(PluginManifest manifest)
+ private void DrawInstalledPluginChangelog(IPluginManifest manifest)
{
ImGuiHelpers.ScaledDummy(5);
@@ -2265,7 +2271,7 @@ internal class PluginInstallerWindow : Window, IDisposable
{
ImGui.Text("Changelog:");
ImGuiHelpers.ScaledDummy(2);
- ImGuiHelpers.SafeTextWrapped(manifest.Changelog);
+ ImGuiHelpers.SafeTextWrapped(manifest.Changelog!);
}
ImGui.EndChild();
@@ -2363,7 +2369,7 @@ internal class PluginInstallerWindow : Window, IDisposable
var isLoadedAndUnloadable = plugin.State == PluginState.Loaded ||
plugin.State == PluginState.DependencyResolutionFailed;
- //StyleModelV1.DalamudStandard.Push();
+ // StyleModelV1.DalamudStandard.Push();
var profileChooserPopupName = $"###pluginProfileChooser{plugin.Manifest.InternalName}";
if (ImGui.BeginPopup(profileChooserPopupName))
@@ -2526,7 +2532,7 @@ internal class PluginInstallerWindow : Window, IDisposable
}
}
- //StyleModelV1.DalamudStandard.Pop();
+ // StyleModelV1.DalamudStandard.Pop();
ImGui.SameLine();
ImGuiHelpers.ScaledDummy(15, 0);
@@ -2621,7 +2627,7 @@ internal class PluginInstallerWindow : Window, IDisposable
}
}
- private void DrawSendFeedbackButton(PluginManifest manifest, bool isTesting)
+ private void DrawSendFeedbackButton(IPluginManifest manifest, bool isTesting)
{
ImGui.SameLine();
if (ImGuiComponents.IconButton(FontAwesomeIcon.Comment))
@@ -2796,7 +2802,7 @@ internal class PluginInstallerWindow : Window, IDisposable
}
}
- private bool DrawPluginImages(LocalPlugin? plugin, PluginManifest manifest, bool isThirdParty, int index)
+ private bool DrawPluginImages(LocalPlugin? plugin, IPluginManifest manifest, bool isThirdParty, int index)
{
var hasImages = this.imageCache.TryGetImages(plugin, manifest, isThirdParty, out var imageTextures);
if (!hasImages || imageTextures.All(x => x == null))
@@ -2871,7 +2877,7 @@ internal class PluginInstallerWindow : Window, IDisposable
return true;
}
- private bool IsManifestFiltered(PluginManifest manifest)
+ private bool IsManifestFiltered(IPluginManifest manifest)
{
var searchString = this.searchText.ToLowerInvariant();
var hasSearchString = !string.IsNullOrWhiteSpace(searchString);
@@ -2889,7 +2895,7 @@ internal class PluginInstallerWindow : Window, IDisposable
(manifest.Tags != null && manifest.Tags.Any(tag => tag.ToLowerInvariant().Contains(searchString))));
}
- private (bool IsInstalled, LocalPlugin Plugin) IsManifestInstalled(PluginManifest? manifest)
+ private (bool IsInstalled, LocalPlugin Plugin) IsManifestInstalled(IPluginManifest? manifest)
{
if (manifest == null) return (false, default);
@@ -3124,9 +3130,9 @@ internal class PluginInstallerWindow : Window, IDisposable
public static string PluginContext_HidePlugin => Loc.Localize("InstallerHidePlugin", "Hide from installer");
- public static string PluginContext_DeletePluginConfig => Loc.Localize("InstallerDeletePluginConfig", "Reset plugin configuration");
+ public static string PluginContext_DeletePluginConfig => Loc.Localize("InstallerDeletePluginConfig", "Reset plugin data");
- public static string PluginContext_DeletePluginConfigReload => Loc.Localize("InstallerDeletePluginConfigReload", "Reset plugin configuration and reload");
+ public static string PluginContext_DeletePluginConfigReload => Loc.Localize("InstallerDeletePluginConfigReload", "Reset plugin data and reload");
#endregion
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs
index dca81c2a7..db455b985 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/ProfileManagerWidget.cs
@@ -77,9 +77,9 @@ internal class ProfileManagerWidget
private void DrawTutorial(string modalTitle)
{
- var _ = true;
+ var open = true;
ImGui.SetNextWindowSize(new Vector2(450, 350), ImGuiCond.Appearing);
- using (var popup = ImRaii.PopupModal(modalTitle, ref _))
+ using (var popup = ImRaii.PopupModal(modalTitle, ref open))
{
if (popup)
{
@@ -399,7 +399,7 @@ internal class ProfileManagerWidget
if (pmPlugin != null)
{
- pic.TryGetIcon(pmPlugin, pmPlugin.Manifest, pmPlugin.Manifest.IsThirdParty, out var icon);
+ pic.TryGetIcon(pmPlugin, pmPlugin.Manifest, pmPlugin.IsThirdParty, out var icon);
icon ??= pic.DefaultIcon;
ImGui.Image(icon.ImGuiHandle, new Vector2(pluginLineHeight));
@@ -596,6 +596,5 @@ internal class ProfileManagerWidget
public static string TutorialCommandsEnd =>
Loc.Localize("ProfileManagerTutorialCommandsEnd", "If you run multiple of these commands, they will be executed in order.");
-
}
}
diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs
index 35b8bbbc7..2b58c21cc 100644
--- a/Dalamud/Plugin/DalamudPluginInterface.cs
+++ b/Dalamud/Plugin/DalamudPluginInterface.cs
@@ -21,6 +21,7 @@ using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal.Windows.PluginInstaller;
using Dalamud.Plugin.Internal;
using Dalamud.Plugin.Internal.Types;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Dalamud.Plugin.Ipc;
using Dalamud.Plugin.Ipc.Exceptions;
using Dalamud.Plugin.Ipc.Internal;
@@ -220,7 +221,7 @@ public sealed class DalamudPluginInterface : IDisposable
///
/// Gets a list of installed plugins along with their current state.
///
- public IEnumerable InstalledPlugins => Service.Get().InstalledPlugins.Select(p => new InstalledPluginState(p.Name, p.Manifest.InternalName, p.IsLoaded, p.Manifest.EffectiveVersion));
+ public IEnumerable InstalledPlugins => Service.Get().InstalledPlugins.Select(p => new InstalledPluginState(p.Name, p.Manifest.InternalName, p.IsLoaded, p.EffectiveVersion));
///
/// Opens the with the plugin name set as search target.
diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index 82def29d0..c98a6bbfc 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -25,6 +25,7 @@ using Dalamud.Networking.Http;
using Dalamud.Plugin.Internal.Exceptions;
using Dalamud.Plugin.Internal.Profiles;
using Dalamud.Plugin.Internal.Types;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Dalamud.Plugin.Ipc.Internal;
using Dalamud.Utility;
using Dalamud.Utility.Timing;
@@ -246,7 +247,7 @@ internal partial class PluginManager : IDisposable, IServiceType
///
/// The manifest to test.
/// Whether or not a testing version is available.
- public static bool HasTestingVersion(PluginManifest manifest)
+ public static bool HasTestingVersion(IPluginManifest manifest)
{
var av = manifest.AssemblyVersion;
var tv = manifest.TestingAssemblyVersion;
@@ -316,7 +317,7 @@ internal partial class PluginManager : IDisposable, IServiceType
///
/// Manifest to check.
/// A value indicating whether testing should be used.
- public bool HasTestingOptIn(PluginManifest manifest)
+ public bool HasTestingOptIn(IPluginManifest manifest)
{
return this.configuration.PluginTestingOptIns!.Any(x => x.InternalName == manifest.InternalName);
}
@@ -327,7 +328,7 @@ internal partial class PluginManager : IDisposable, IServiceType
///
/// Manifest to check.
/// A value indicating whether testing should be used.
- public bool UseTesting(PluginManifest manifest)
+ public bool UseTesting(IPluginManifest manifest)
{
if (!this.configuration.DoPluginTest)
return false;
diff --git a/Dalamud/Plugin/Internal/Types/AvailablePluginUpdate.cs b/Dalamud/Plugin/Internal/Types/AvailablePluginUpdate.cs
index 13523a379..36823b389 100644
--- a/Dalamud/Plugin/Internal/Types/AvailablePluginUpdate.cs
+++ b/Dalamud/Plugin/Internal/Types/AvailablePluginUpdate.cs
@@ -1,3 +1,5 @@
+using Dalamud.Plugin.Internal.Types.Manifest;
+
namespace Dalamud.Plugin.Internal.Types;
///
diff --git a/Dalamud/Plugin/Internal/Types/LocalDevPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalDevPlugin.cs
index 498bea874..98784ce64 100644
--- a/Dalamud/Plugin/Internal/Types/LocalDevPlugin.cs
+++ b/Dalamud/Plugin/Internal/Types/LocalDevPlugin.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Dalamud.Configuration.Internal;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Logging.Internal;
+using Dalamud.Plugin.Internal.Types.Manifest;
namespace Dalamud.Plugin.Internal.Types;
diff --git a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
index 42fb40f91..5ad09ebc3 100644
--- a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
+++ b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
@@ -11,11 +11,11 @@ using Dalamud.Game.Gui.Dtr;
using Dalamud.Interface.GameFonts;
using Dalamud.Interface.Internal;
using Dalamud.IoC.Internal;
-using Dalamud.Logging;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Internal.Exceptions;
using Dalamud.Plugin.Internal.Loader;
using Dalamud.Plugin.Internal.Profiles;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Dalamud.Utility;
namespace Dalamud.Plugin.Internal.Types;
@@ -39,6 +39,8 @@ internal class LocalPlugin : IDisposable
private Type? pluginType;
private IDalamudPlugin? instance;
+ private LocalPluginManifest manifest;
+
///
/// Initializes a new instance of the class.
///
@@ -111,7 +113,7 @@ internal class LocalPlugin : IDisposable
// If the parameter manifest was null
if (manifest == null)
{
- this.Manifest = new LocalPluginManifest()
+ this.manifest = new LocalPluginManifest()
{
Author = "developer",
Name = Path.GetFileNameWithoutExtension(this.DllFile.Name),
@@ -125,11 +127,11 @@ internal class LocalPlugin : IDisposable
// Save the manifest to disk so there won't be any problems later.
// We'll update the name property after it can be retrieved from the instance.
- this.Manifest.Save(this.manifestFile, "manifest was null");
+ this.manifest.Save(this.manifestFile, "manifest was null");
}
else
{
- this.Manifest = manifest;
+ this.manifest = manifest;
}
var needsSaveDueToLegacyFiles = false;
@@ -139,7 +141,7 @@ internal class LocalPlugin : IDisposable
if (this.disabledFile.Exists)
{
#pragma warning disable CS0618
- this.Manifest.Disabled = true;
+ this.manifest.Disabled = true;
#pragma warning restore CS0618
this.disabledFile.Delete();
@@ -150,15 +152,15 @@ internal class LocalPlugin : IDisposable
this.testingFile = LocalPluginManifest.GetTestingFile(this.DllFile);
if (this.testingFile.Exists)
{
- this.Manifest.Testing = true;
+ this.manifest.Testing = true;
this.testingFile.Delete();
needsSaveDueToLegacyFiles = true;
}
var pluginManager = Service.Get();
- this.IsBanned = pluginManager.IsManifestBanned(this.Manifest) && !this.IsDev;
- this.BanReason = pluginManager.GetBanReason(this.Manifest);
+ this.IsBanned = pluginManager.IsManifestBanned(this.manifest) && !this.IsDev;
+ this.BanReason = pluginManager.GetBanReason(this.manifest);
if (needsSaveDueToLegacyFiles)
this.SaveManifest("legacy");
@@ -175,9 +177,9 @@ internal class LocalPlugin : IDisposable
public FileInfo DllFile { get; }
///
- /// Gets the plugin manifest, if one exists.
+ /// Gets the plugin manifest.
///
- public LocalPluginManifest Manifest { get; private set; }
+ public ILocalPluginManifest Manifest => this.manifest;
///
/// Gets or sets the current state of the plugin.
@@ -193,12 +195,12 @@ internal class LocalPlugin : IDisposable
///
/// Gets the plugin name from the manifest.
///
- public string Name => this.Manifest.Name;
+ public string Name => this.manifest.Name;
///
/// Gets the plugin internal name from the manifest.
///
- public string InternalName => this.Manifest.InternalName;
+ public string InternalName => this.manifest.InternalName;
///
/// Gets an optional reason, if the plugin is banned.
@@ -220,23 +222,23 @@ internal class LocalPlugin : IDisposable
/// INCLUDES the default profile.
///
public bool IsWantedByAnyProfile =>
- Service.Get().GetWantStateAsync(this.Manifest.InternalName, false, false).GetAwaiter().GetResult();
+ Service.Get().GetWantStateAsync(this.manifest.InternalName, false, false).GetAwaiter().GetResult();
///
/// Gets a value indicating whether this plugin's API level is out of date.
///
- public bool IsOutdated => this.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel;
+ public bool IsOutdated => this.manifest.DalamudApiLevel < PluginManager.DalamudApiLevel;
///
/// Gets a value indicating whether the plugin is for testing use only.
///
- public bool IsTesting => this.Manifest.IsTestingExclusive || this.Manifest.Testing;
+ public bool IsTesting => this.manifest.IsTestingExclusive || this.manifest.Testing;
///
/// Gets a value indicating whether or not this plugin is orphaned(belongs to a repo) or not.
///
public bool IsOrphaned => !this.IsDev &&
- !this.Manifest.InstalledFromUrl.IsNullOrEmpty() && // TODO(api8): Remove this, all plugins will have a proper flag
+ !this.manifest.InstalledFromUrl.IsNullOrEmpty() && // TODO(api8): Remove this, all plugins will have a proper flag
this.GetSourceRepository() == null;
///
@@ -244,7 +246,7 @@ internal class LocalPlugin : IDisposable
///
public bool IsDecommissioned => !this.IsDev &&
this.GetSourceRepository()?.State == PluginRepositoryState.Success &&
- this.GetSourceRepository()?.PluginMaster?.FirstOrDefault(x => x.InternalName == this.Manifest.InternalName) == null;
+ this.GetSourceRepository()?.PluginMaster?.FirstOrDefault(x => x.InternalName == this.manifest.InternalName) == null;
///
/// Gets a value indicating whether this plugin has been banned.
@@ -256,12 +258,23 @@ internal class LocalPlugin : IDisposable
///
public bool IsDev => this is LocalDevPlugin;
+ ///
+ /// Gets a value indicating whether this manifest is associated with a plugin that was installed from a third party
+ /// repo.
+ ///
+ public bool IsThirdParty => this.manifest.IsThirdParty;
+
///
/// Gets a value indicating whether this plugin should be allowed to load.
///
public bool ApplicableForLoad => !this.IsBanned && !this.IsDecommissioned && !this.IsOrphaned && !this.IsOutdated
&& !(!this.IsDev && this.State == PluginState.UnloadError) && this.CheckPolicy();
+ ///
+ /// Gets the effective version of this plugin.
+ ///
+ public Version EffectiveVersion => this.manifest.EffectiveVersion;
+
///
/// Gets the service scope for this plugin.
///
@@ -277,7 +290,7 @@ internal class LocalPlugin : IDisposable
if (this.instance != null)
{
didPluginDispose = true;
- if (this.Manifest.CanUnloadAsync || framework == null)
+ if (this.manifest.CanUnloadAsync || framework == null)
this.instance.Dispose();
else
framework.RunOnFrameworkThread(() => this.instance.Dispose()).Wait();
@@ -316,7 +329,7 @@ internal class LocalPlugin : IDisposable
await Service.GetAsync();
await Service.GetAsync();
- if (this.Manifest.LoadRequiredState == 0)
+ if (this.manifest.LoadRequiredState == 0)
_ = await Service.GetAsync();
await this.pluginLoadStateLock.WaitAsync();
@@ -329,9 +342,9 @@ internal class LocalPlugin : IDisposable
}
// If we reload a plugin we don't want to delete it. Makes sense, right?
- if (this.Manifest.ScheduledForDeletion)
+ if (this.manifest.ScheduledForDeletion)
{
- this.Manifest.ScheduledForDeletion = false;
+ this.manifest.ScheduledForDeletion = false;
this.SaveManifest("Scheduled for deletion, but loading");
}
@@ -363,13 +376,13 @@ internal class LocalPlugin : IDisposable
throw new ArgumentOutOfRangeException(this.State.ToString());
}
- if (pluginManager.IsManifestBanned(this.Manifest) && !this.IsDev)
+ if (pluginManager.IsManifestBanned(this.manifest) && !this.IsDev)
throw new BannedPluginException($"Unable to load {this.Name}, banned");
- if (this.Manifest.ApplicableVersion < startInfo.GameVersion)
+ if (this.manifest.ApplicableVersion < startInfo.GameVersion)
throw new InvalidPluginOperationException($"Unable to load {this.Name}, no applicable version");
- if (this.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !pluginManager.LoadAllApiLevels)
+ if (this.manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !pluginManager.LoadAllApiLevels)
throw new InvalidPluginOperationException($"Unable to load {this.Name}, incompatible API level");
// We might want to throw here?
@@ -390,8 +403,8 @@ internal class LocalPlugin : IDisposable
{
Log.Error(
"==== IMPORTANT MESSAGE TO {0}, THE DEVELOPER OF {1} ====",
- this.Manifest.Author!,
- this.Manifest.InternalName);
+ this.manifest.Author!,
+ this.manifest.InternalName);
Log.Error(
"YOU ARE INCLUDING DALAMUD DEPENDENCIES IN YOUR BUILDS!!!");
Log.Error(
@@ -459,7 +472,7 @@ internal class LocalPlugin : IDisposable
this.ServiceScope = ioc.GetScope();
this.ServiceScope.RegisterPrivateScopes(this); // Add this LocalPlugin as a private scope, so services can get it
- if (this.Manifest.LoadSync && this.Manifest.LoadRequiredState is 0 or 1)
+ if (this.manifest.LoadSync && this.manifest.LoadRequiredState is 0 or 1)
{
this.instance = await framework.RunOnFrameworkThread(
() => this.ServiceScope.CreateAsync(this.pluginType!, this.DalamudInterface!)) as IDalamudPlugin;
@@ -480,10 +493,10 @@ internal class LocalPlugin : IDisposable
}
// In-case the manifest name was a placeholder. Can occur when no manifest was included.
- if (this.Manifest.Name.IsNullOrEmpty() && !this.IsDev)
+ if (this.manifest.Name.IsNullOrEmpty() && !this.IsDev)
{
- this.Manifest.Name = this.instance.Name;
- this.Manifest.Save(this.manifestFile, "manifest name null or empty");
+ this.manifest.Name = this.instance.Name;
+ this.manifest.Save(this.manifestFile, "manifest name null or empty");
}
this.State = PluginState.Loaded;
@@ -515,7 +528,6 @@ internal class LocalPlugin : IDisposable
{
var configuration = Service.Get();
var framework = Service.GetNullable();
- var ioc = await Service.GetAsync();
await this.pluginLoadStateLock.WaitAsync();
try
@@ -544,7 +556,7 @@ internal class LocalPlugin : IDisposable
this.State = PluginState.Unloading;
Log.Information($"Unloading {this.DllFile.Name}");
- if (this.Manifest.CanUnloadAsync || framework == null)
+ if (this.manifest.CanUnloadAsync || framework == null)
this.instance?.Dispose();
else
await framework.RunOnFrameworkThread(() => this.instance?.Dispose());
@@ -612,7 +624,7 @@ internal class LocalPlugin : IDisposable
if (startInfo.NoLoadPlugins)
return false;
- if (startInfo.NoLoadThirdPartyPlugins && this.Manifest.IsThirdParty)
+ if (startInfo.NoLoadThirdPartyPlugins && this.manifest.IsThirdParty)
return false;
if (manager.SafeMode)
@@ -627,7 +639,7 @@ internal class LocalPlugin : IDisposable
/// Schedule or cancel the deletion.
public void ScheduleDeletion(bool status = true)
{
- this.Manifest.ScheduledForDeletion = status;
+ this.manifest.ScheduledForDeletion = status;
this.SaveManifest("scheduling for deletion");
}
@@ -636,12 +648,12 @@ internal class LocalPlugin : IDisposable
///
public void ReloadManifest()
{
- var manifest = LocalPluginManifest.GetManifestFile(this.DllFile);
- if (manifest.Exists)
+ var manifestPath = LocalPluginManifest.GetManifestFile(this.DllFile);
+ if (manifestPath.Exists)
{
// var isDisabled = this.IsDisabled; // saving the internal state because it could have been deleted
- this.Manifest = LocalPluginManifest.Load(manifest) ?? throw new Exception("Could not reload manifest.");
- // this.Manifest.Disabled = isDisabled;
+ this.manifest = LocalPluginManifest.Load(manifestPath) ?? throw new Exception("Could not reload manifest.");
+ // this.manifest.Disabled = isDisabled;
this.SaveManifest("dev reload");
}
@@ -659,10 +671,10 @@ internal class LocalPlugin : IDisposable
var repos = Service.Get().Repos;
return repos.FirstOrDefault(x =>
{
- if (!x.IsThirdParty && !this.Manifest.IsThirdParty)
+ if (!x.IsThirdParty && !this.manifest.IsThirdParty)
return true;
- return x.PluginMasterUrl == this.Manifest.InstalledFromUrl;
+ return x.PluginMasterUrl == this.manifest.InstalledFromUrl;
});
}
@@ -675,5 +687,5 @@ internal class LocalPlugin : IDisposable
config.SharedAssemblies.Add(typeof(Lumina.Excel.ExcelSheetImpl).Assembly.GetName());
}
- private void SaveManifest(string reason) => this.Manifest.Save(this.manifestFile, reason);
+ private void SaveManifest(string reason) => this.manifest.Save(this.manifestFile, reason);
}
diff --git a/Dalamud/Plugin/Internal/Types/Manifest/ILocalPluginManifest.cs b/Dalamud/Plugin/Internal/Types/Manifest/ILocalPluginManifest.cs
new file mode 100644
index 000000000..97365d1e5
--- /dev/null
+++ b/Dalamud/Plugin/Internal/Types/Manifest/ILocalPluginManifest.cs
@@ -0,0 +1,19 @@
+namespace Dalamud.Plugin.Internal.Types.Manifest;
+
+///
+/// Public interface for the local plugin manifest.
+///
+public interface ILocalPluginManifest : IPluginManifest
+{
+ ///
+ /// Gets the 3rd party repo URL that this plugin was installed from. Used to display where the plugin was
+ /// sourced from on the installed plugin view. This should not be included in the plugin master. This value is null
+ /// when installed from the main repo.
+ ///
+ public string InstalledFromUrl { get; }
+
+ ///
+ /// Gets a value indicating whether the plugin should be deleted during the next cleanup.
+ ///
+ public bool ScheduledForDeletion { get; }
+}
diff --git a/Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs b/Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs
new file mode 100644
index 000000000..9e052efad
--- /dev/null
+++ b/Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+
+namespace Dalamud.Plugin.Internal.Types.Manifest;
+
+///
+/// Public interface for the base plugin manifest.
+///
+public interface IPluginManifest
+{
+ ///
+ /// Gets the internal name of the plugin, which should match the assembly name of the plugin.
+ ///
+ public string InternalName { get; }
+
+ ///
+ /// Gets the public name of the plugin.
+ ///
+ public string Name { get; }
+
+ ///
+ /// Gets a punchline of the plugins functions.
+ ///
+ public string? Punchline { get; }
+
+ ///
+ /// Gets the author/s of the plugin.
+ ///
+ public string Author { get; }
+
+ ///
+ /// Gets a value indicating whether the plugin can be unloaded asynchronously.
+ ///
+ public bool CanUnloadAsync { get; }
+
+ ///
+ /// Gets the assembly version of the plugin.
+ ///
+ public Version AssemblyVersion { get; }
+
+ ///
+ /// Gets the assembly version of the plugin's testing variant.
+ ///
+ public Version? TestingAssemblyVersion { get; }
+
+ ///
+ /// Gets the DIP17 channel name.
+ ///
+ public string? Dip17Channel { get; }
+
+ ///
+ /// Gets the last time this plugin was updated.
+ ///
+ public long LastUpdate { get; }
+
+ ///
+ /// Gets a changelog, null if none exists.
+ ///
+ public string? Changelog { get; }
+
+ ///
+ /// Gets a list of tags that apply to this plugin.
+ ///
+ public List? Tags { get; }
+
+ ///
+ /// Gets the API level of this plugin. For the current API level, please see
+ /// for the currently used API level.
+ ///
+ public int DalamudApiLevel { get; }
+
+ ///
+ /// Gets the number of downloads this plugin has.
+ ///
+ public long DownloadCount { get; }
+
+ ///
+ /// Gets a value indicating whether the plugin supports profiles.
+ ///
+ public bool SupportsProfiles { get; }
+
+ ///
+ /// Gets an URL to the website or source code of the plugin.
+ ///
+ public string? RepoUrl { get; }
+
+ ///
+ /// Gets a description of the plugins functions.
+ ///
+ public string? Description { get; }
+
+ ///
+ /// Gets a message that is shown to users when sending feedback.
+ ///
+ public string? FeedbackMessage { get; }
+
+ ///
+ /// Gets a value indicating whether the plugin is only available for testing.
+ ///
+ public bool IsTestingExclusive { get; }
+
+ ///
+ /// Gets a list of screenshot image URLs to show in the plugin installer.
+ ///
+ public List? ImageUrls { get; }
+
+ ///
+ /// Gets an URL for the plugin's icon.
+ ///
+ public string? IconUrl { get; }
+}
diff --git a/Dalamud/Plugin/Internal/Types/LocalPluginManifest.cs b/Dalamud/Plugin/Internal/Types/Manifest/LocalPluginManifest.cs
similarity index 86%
rename from Dalamud/Plugin/Internal/Types/LocalPluginManifest.cs
rename to Dalamud/Plugin/Internal/Types/Manifest/LocalPluginManifest.cs
index bcb8cd9e7..4b4bf5d6e 100644
--- a/Dalamud/Plugin/Internal/Types/LocalPluginManifest.cs
+++ b/Dalamud/Plugin/Internal/Types/Manifest/LocalPluginManifest.cs
@@ -5,13 +5,13 @@ using Dalamud.Utility;
using Newtonsoft.Json;
using Serilog;
-namespace Dalamud.Plugin.Internal.Types;
+namespace Dalamud.Plugin.Internal.Types.Manifest;
///
/// Information about a plugin, packaged in a json file with the DLL. This variant includes additional information such as
/// if the plugin is disabled and if it was installed from a testing URL. This is designed for use with manifests on disk.
///
-internal record LocalPluginManifest : PluginManifest
+internal record LocalPluginManifest : PluginManifest, ILocalPluginManifest
{
///
/// Flag indicating that a plugin was installed from the official repo.
@@ -38,16 +38,10 @@ internal record LocalPluginManifest : PluginManifest
///
public bool Testing { get; set; }
- ///
- /// Gets or sets a value indicating whether the plugin should be deleted during the next cleanup.
- ///
+ ///
public bool ScheduledForDeletion { get; set; }
- ///
- /// Gets or sets the 3rd party repo URL that this plugin was installed from. Used to display where the plugin was
- /// sourced from on the installed plugin view. This should not be included in the plugin master. This value is null
- /// when installed from the main repo.
- ///
+ ///
public string InstalledFromUrl { get; set; } = string.Empty;
///
@@ -61,11 +55,6 @@ internal record LocalPluginManifest : PluginManifest
///
public Version EffectiveVersion => this.Testing && this.TestingAssemblyVersion != null ? this.TestingAssemblyVersion : this.AssemblyVersion;
- ///
- /// Gets a value indicating whether this plugin is eligible for testing.
- ///
- public bool IsAvailableForTesting => this.TestingAssemblyVersion != null && this.TestingAssemblyVersion > this.AssemblyVersion;
-
///
/// Save a plugin manifest to file.
///
diff --git a/Dalamud/Plugin/Internal/Types/RemotePluginManifest.cs b/Dalamud/Plugin/Internal/Types/Manifest/RemotePluginManifest.cs
similarity index 71%
rename from Dalamud/Plugin/Internal/Types/RemotePluginManifest.cs
rename to Dalamud/Plugin/Internal/Types/Manifest/RemotePluginManifest.cs
index 09084d569..952650c72 100644
--- a/Dalamud/Plugin/Internal/Types/RemotePluginManifest.cs
+++ b/Dalamud/Plugin/Internal/Types/Manifest/RemotePluginManifest.cs
@@ -1,7 +1,7 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
-namespace Dalamud.Plugin.Internal.Types;
+namespace Dalamud.Plugin.Internal.Types.Manifest;
///
/// Information about a plugin, packaged in a json file with the DLL. This variant includes additional information such as
@@ -16,4 +16,9 @@ internal record RemotePluginManifest : PluginManifest
///
[JsonIgnore]
public PluginRepository SourceRepo { get; set; } = null!;
+
+ ///
+ /// Gets a value indicating whether this plugin is eligible for testing.
+ ///
+ public bool IsAvailableForTesting => this.TestingAssemblyVersion != null && this.TestingAssemblyVersion > this.AssemblyVersion;
}
diff --git a/Dalamud/Plugin/Internal/Types/PluginDef.cs b/Dalamud/Plugin/Internal/Types/PluginDef.cs
index c5dbede0d..049e58d7d 100644
--- a/Dalamud/Plugin/Internal/Types/PluginDef.cs
+++ b/Dalamud/Plugin/Internal/Types/PluginDef.cs
@@ -1,5 +1,7 @@
using System.IO;
+using Dalamud.Plugin.Internal.Types.Manifest;
+
namespace Dalamud.Plugin.Internal.Types;
///
diff --git a/Dalamud/Plugin/Internal/Types/PluginManifest.cs b/Dalamud/Plugin/Internal/Types/PluginManifest.cs
index 71051e666..0b5ec26fc 100644
--- a/Dalamud/Plugin/Internal/Types/PluginManifest.cs
+++ b/Dalamud/Plugin/Internal/Types/PluginManifest.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Dalamud.Game;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Newtonsoft.Json;
namespace Dalamud.Plugin.Internal.Types;
@@ -9,41 +10,29 @@ namespace Dalamud.Plugin.Internal.Types;
///
/// Information about a plugin, packaged in a json file with the DLL.
///
-internal record PluginManifest
+internal record PluginManifest : IPluginManifest
{
- ///
- /// Gets the author/s of the plugin.
- ///
+ ///
[JsonProperty]
public string? Author { get; init; }
- ///
- /// Gets or sets the public name of the plugin.
- ///
+ ///
[JsonProperty]
public string Name { get; set; } = null!;
- ///
- /// Gets a punchline of the plugins functions.
- ///
+ ///
[JsonProperty]
public string? Punchline { get; init; }
- ///
- /// Gets a description of the plugins functions.
- ///
+ ///
[JsonProperty]
public string? Description { get; init; }
- ///
- /// Gets a changelog.
- ///
+ ///
[JsonProperty]
public string? Changelog { get; init; }
- ///
- /// Gets a list of tags defined on the plugin.
- ///
+ ///
[JsonProperty]
public List? Tags { get; init; }
@@ -60,33 +49,23 @@ internal record PluginManifest
[JsonProperty]
public bool IsHide { get; init; }
- ///
- /// Gets the internal name of the plugin, which should match the assembly name of the plugin.
- ///
+ ///
[JsonProperty]
- public string InternalName { get; init; } = null!;
+ public string InternalName { get; set; } = null!;
- ///
- /// Gets the current assembly version of the plugin.
- ///
+ ///
[JsonProperty]
- public Version AssemblyVersion { get; init; } = null!;
+ public Version AssemblyVersion { get; set; } = null!;
- ///
- /// Gets the current testing assembly version of the plugin.
- ///
+ ///
[JsonProperty]
public Version? TestingAssemblyVersion { get; init; }
- ///
- /// Gets a value indicating whether the plugin is only available for testing.
- ///
+ ///
[JsonProperty]
public bool IsTestingExclusive { get; init; }
- ///
- /// Gets an URL to the website or source code of the plugin.
- ///
+ ///
[JsonProperty]
public string? RepoUrl { get; init; }
@@ -97,24 +76,17 @@ internal record PluginManifest
[JsonConverter(typeof(GameVersionConverter))]
public GameVersion? ApplicableVersion { get; init; } = GameVersion.Any;
- ///
- /// Gets the API level of this plugin. For the current API level, please see
- /// for the currently used API level.
- ///
+ ///
[JsonProperty]
public int DalamudApiLevel { get; init; } = PluginManager.DalamudApiLevel;
- ///
- /// Gets the number of downloads this plugin has.
- ///
+ ///
[JsonProperty]
public long DownloadCount { get; init; }
- ///
- /// Gets the last time this plugin was updated.
- ///
+ ///
[JsonProperty]
- public long LastUpdate { get; init; }
+ public long LastUpdate { get; set; }
///
/// Gets the download link used to install the plugin.
@@ -156,26 +128,18 @@ internal record PluginManifest
[JsonProperty]
public int LoadPriority { get; init; }
- ///
- /// Gets a value indicating whether the plugin can be unloaded asynchronously.
- ///
+ ///
[JsonProperty]
- public bool CanUnloadAsync { get; init; }
+ public bool CanUnloadAsync { get; set; }
- ///
- /// Gets a value indicating whether the plugin supports profiles.
- ///
+ ///
[JsonProperty]
public bool SupportsProfiles { get; init; } = true;
- ///
- /// Gets a list of screenshot image URLs to show in the plugin installer.
- ///
+ ///
public List? ImageUrls { get; init; }
- ///
- /// Gets an URL for the plugin's icon.
- ///
+ ///
public string? IconUrl { get; init; }
///
@@ -183,21 +147,10 @@ internal record PluginManifest
///
public bool AcceptsFeedback { get; init; } = true;
- ///
- /// Gets a message that is shown to users when sending feedback.
- ///
+ ///
public string? FeedbackMessage { get; init; }
- ///
- /// Gets a value indicating whether this plugin is DIP17.
- /// To be removed.
- ///
- [JsonProperty("_isDip17Plugin")]
- public bool IsDip17Plugin { get; init; } = false;
-
- ///
- /// Gets the DIP17 channel name.
- ///
+ ///
[JsonProperty("_Dip17Channel")]
public string? Dip17Channel { get; init; }
}
diff --git a/Dalamud/Plugin/Internal/Types/PluginRepository.cs b/Dalamud/Plugin/Internal/Types/PluginRepository.cs
index b51a3355c..a1097abce 100644
--- a/Dalamud/Plugin/Internal/Types/PluginRepository.cs
+++ b/Dalamud/Plugin/Internal/Types/PluginRepository.cs
@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Dalamud.Logging.Internal;
using Dalamud.Networking.Http;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Dalamud.Utility;
using Newtonsoft.Json;
diff --git a/Dalamud/Support/BugBait.cs b/Dalamud/Support/BugBait.cs
index cdbf94616..22628303e 100644
--- a/Dalamud/Support/BugBait.cs
+++ b/Dalamud/Support/BugBait.cs
@@ -3,7 +3,7 @@ using System.Text;
using System.Threading.Tasks;
using Dalamud.Networking.Http;
-using Dalamud.Plugin.Internal.Types;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Dalamud.Utility;
using Newtonsoft.Json;
@@ -25,7 +25,7 @@ internal static class BugBait
/// The reporter name.
/// Whether or not the most recent exception to occur should be included in the report.
/// A representing the asynchronous operation.
- public static async Task SendFeedback(PluginManifest plugin, bool isTesting, string content, string reporter, bool includeException)
+ public static async Task SendFeedback(IPluginManifest plugin, bool isTesting, string content, string reporter, bool includeException)
{
if (content.IsNullOrWhitespace())
return;
diff --git a/Dalamud/Support/Troubleshooting.cs b/Dalamud/Support/Troubleshooting.cs
index ef1897eeb..9893451f4 100644
--- a/Dalamud/Support/Troubleshooting.cs
+++ b/Dalamud/Support/Troubleshooting.cs
@@ -7,7 +7,7 @@ using Dalamud.Configuration;
using Dalamud.Configuration.Internal;
using Dalamud.Interface.Internal;
using Dalamud.Plugin.Internal;
-using Dalamud.Plugin.Internal.Types;
+using Dalamud.Plugin.Internal.Types.Manifest;
using Dalamud.Utility;
using Newtonsoft.Json;
using Serilog;
@@ -67,7 +67,7 @@ public static class Troubleshooting
{
var payload = new TroubleshootingPayload
{
- LoadedPlugins = pluginManager?.InstalledPlugins?.Select(x => x.Manifest)?.OrderByDescending(x => x.InternalName).ToArray(),
+ LoadedPlugins = pluginManager?.InstalledPlugins?.Select(x => x.Manifest as LocalPluginManifest)?.OrderByDescending(x => x.InternalName).ToArray(),
PluginStates = pluginManager?.InstalledPlugins?.Where(x => !x.IsDev).ToDictionary(x => x.Manifest.InternalName, x => x.IsBanned ? "Banned" : x.State.ToString()),
EverStartedLoadingPlugins = pluginManager?.InstalledPlugins.Where(x => x.HasEverStartedLoad).Select(x => x.InternalName).ToList(),
DalamudVersion = Util.AssemblyVersion,
diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs
index 60b1901d0..038273eb6 100644
--- a/Dalamud/Utility/Util.cs
+++ b/Dalamud/Utility/Util.cs
@@ -674,7 +674,7 @@ public static class Util
}
///
- /// Print formatted GameObject Information to ImGui
+ /// Print formatted GameObject Information to ImGui.
///
/// Game Object to Display.
/// Display Tag.
diff --git a/sign.ps1 b/sign.ps1
new file mode 100644
index 000000000..73fb6cc67
--- /dev/null
+++ b/sign.ps1
@@ -0,0 +1,71 @@
+# Get the certificate and password from environment variables
+$certificateBase64 = $env:CODESIGN_CERT_PFX
+$certificatePassword = $env:CODESIGN_CERT_PASSWORD
+
+# Write the certificate to a file
+$certificatePath = Join-Path -Path $env:TEMP -ChildPath 'certificate.pfx'
+$certificateBytes = [Convert]::FromBase64String($certificateBase64)
+[System.IO.File]::WriteAllBytes($certificatePath, $certificateBytes)
+
+# Define the function to find the path to signtool.exe
+function Get-SignToolPath {
+ # Array of common installation directories for Windows SDK
+ $sdkInstallationDirs = @(
+ "$env:ProgramFiles (x86)\Windows Kits\10\bin\x64",
+ "$env:ProgramFiles\Windows Kits\10\bin\x64",
+ "$env:ProgramFiles (x86)\Windows Kits\10\App Certification Kit"
+ )
+
+ foreach ($dir in $sdkInstallationDirs) {
+ $path = Join-Path -Path $dir -ChildPath 'signtool.exe'
+ #Write-Host $path
+ if (Test-Path -Path $path) {
+ return $path
+ }
+ }
+
+ throw "Could not find signtool.exe. Make sure the Windows SDK is installed."
+}
+
+# Find the path to signtool.exe
+$signtoolPath = Get-SignToolPath
+
+# Define the function to code-sign a file
+function Sign-File {
+ param (
+ [Parameter(Mandatory=$true)]
+ [String]$FilePath
+ )
+
+ # Check if the file is already code-signed
+ $signature = Get-AuthenticodeSignature -FilePath $FilePath -ErrorAction SilentlyContinue
+ if ($signature.status -ne "NotSigned") {
+ Write-Host "File '$FilePath' is already code-signed. Skipping."
+ return
+ }
+
+ # Code-sign the file using signtool
+ Write-Host "Code-signing file '$FilePath'..."
+ & $signtoolPath sign /tr http://timestamp.digicert.com /td sha256 /v /fd sha256 /f $certificatePath /p $certificatePassword $FilePath
+}
+
+# Define the function to recursively code-sign files in a directory
+function Sign-FilesRecursively {
+ param (
+ [Parameter(Mandatory=$true)]
+ [String]$DirectoryPath
+ )
+
+ Write-Host $DirectoryPath
+
+ # Get all exe and dll files recursively
+ dir $DirectoryPath -recurse | where {$_.extension -in ".exe",".dll"} | ForEach-Object {
+ Sign-File -FilePath $_.FullName
+ }
+}
+
+# Usage: Provide the directory path as an argument to sign files recursively
+Sign-FilesRecursively -DirectoryPath $args[0]
+
+# Remove the temporary certificate file
+Remove-Item -Path $certificatePath