diff --git a/.editorconfig b/.editorconfig
index 72d2313af..109c9f406 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -118,7 +118,11 @@ resharper_arrange_type_member_modifiers_highlighting = hint
resharper_arrange_type_modifiers_highlighting = hint
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = none
+resharper_foreach_can_be_converted_to_query_using_another_get_enumerator_highlighting = none
+resharper_foreach_can_be_partly_converted_to_query_using_another_get_enumerator_highlighting = none
resharper_invert_if_highlighting = none
+resharper_loop_can_be_converted_to_query_highlighting = none
+resharper_method_has_async_overload_highlighting = none
resharper_redundant_base_qualifier_highlighting = none
resharper_suggest_var_or_type_built_in_types_highlighting = hint
resharper_suggest_var_or_type_elsewhere_highlighting = hint
diff --git a/Dalamud.sln.DotSettings b/Dalamud.sln.DotSettings
index 4653085d4..690f1a7ac 100644
--- a/Dalamud.sln.DotSettings
+++ b/Dalamud.sln.DotSettings
@@ -47,12 +47,15 @@
True
True
True
+ True
True
True
True
True
True
True
+ True
+ True
True
True
True
diff --git a/Dalamud/Game/ChatHandlers.cs b/Dalamud/Game/ChatHandlers.cs
index e1dcad965..701e7624e 100644
--- a/Dalamud/Game/ChatHandlers.cs
+++ b/Dalamud/Game/ChatHandlers.cs
@@ -18,6 +18,7 @@ using Dalamud.Interface.Internal.Windows;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Internal;
+using Dalamud.Plugin.Internal.Types;
using Dalamud.Utility;
using Serilog;
@@ -302,7 +303,7 @@ namespace Dalamud.Game
{
if (configuration.AutoUpdatePlugins)
{
- pluginManager.PrintUpdatedPlugins(updatedPlugins, Loc.Localize("DalamudPluginAutoUpdate", "Auto-update:"));
+ PluginManager.PrintUpdatedPlugins(updatedPlugins, Loc.Localize("DalamudPluginAutoUpdate", "Auto-update:"));
notifications.AddNotification(Loc.Localize("NotificationUpdatedPlugins", "{0} of your plugins were updated.").Format(updatedPlugins.Count), Loc.Localize("NotificationAutoUpdate", "Auto-Update"), NotificationType.Info);
}
else
diff --git a/Dalamud/Interface/Internal/Windows/PluginImageCache.cs b/Dalamud/Interface/Internal/Windows/PluginImageCache.cs
index 10f972106..2e714a8c8 100644
--- a/Dalamud/Interface/Internal/Windows/PluginImageCache.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginImageCache.cs
@@ -320,7 +320,7 @@ namespace Dalamud.Interface.Internal.Windows
isThirdParty = true;
}
- var useTesting = pluginManager.UseTesting(manifest);
+ var useTesting = PluginManager.UseTesting(manifest);
var url = this.GetPluginIconUrl(manifest, isThirdParty, useTesting);
if (!url.IsNullOrEmpty())
@@ -441,7 +441,7 @@ namespace Dalamud.Interface.Internal.Windows
isThirdParty = true;
}
- var useTesting = pluginManager.UseTesting(manifest);
+ var useTesting = PluginManager.UseTesting(manifest);
var urls = this.GetPluginImageUrls(manifest, isThirdParty, useTesting);
if (urls != null)
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
index 265dcb58d..893577754 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
@@ -348,7 +348,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
if (this.updatePluginCount > 0)
{
- pluginManager.PrintUpdatedPlugins(this.updatedPlugins, Locs.PluginUpdateHeader_Chatbox);
+ PluginManager.PrintUpdatedPlugins(this.updatedPlugins, Locs.PluginUpdateHeader_Chatbox);
notifications.AddNotification(Locs.Notifications_UpdatesInstalled(this.updatePluginCount), Locs.Notifications_UpdatesInstalledTitle, NotificationType.Success);
var installedGroupIdx = this.categoryManager.GroupList.TakeWhile(
@@ -1251,7 +1251,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
var notifications = Service.Get();
var pluginManager = Service.Get();
- var useTesting = pluginManager.UseTesting(manifest);
+ var useTesting = PluginManager.UseTesting(manifest);
var wasSeen = this.WasPluginSeen(manifest.InternalName);
// Check for valid versions
diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index 9cc09e566..2893f6ab2 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -104,7 +104,7 @@ namespace Dalamud.Plugin.Internal
///
/// Gets a value indicating whether plugins are not still loading from boot.
///
- public bool PluginsReady { get; private set; } = false;
+ public bool PluginsReady { get; private set; }
///
/// Gets a value indicating whether all added repos are not in progress.
@@ -121,6 +121,82 @@ namespace Dalamud.Plugin.Internal
///
public PluginConfigurations PluginConfigs { get; }
+ ///
+ /// Print to chat any plugin updates and whether they were successful.
+ ///
+ /// The list of updated plugin metadata.
+ /// The header text to send to chat prior to any update info.
+ public static void PrintUpdatedPlugins(List? updateMetadata, string header)
+ {
+ var chatGui = Service.Get();
+
+ if (updateMetadata is { Count: > 0 })
+ {
+ chatGui.Print(header);
+
+ foreach (var metadata in updateMetadata)
+ {
+ if (metadata.WasUpdated)
+ {
+ chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version));
+ }
+ else
+ {
+ chatGui.PrintChat(new XivChatEntry
+ {
+ Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version),
+ Type = XivChatType.Urgent,
+ });
+ }
+ }
+ }
+ }
+
+ ///
+ /// For a given manifest, determine if the testing version should be used over the normal version.
+ /// The higher of the two versions is calculated after checking other settings.
+ ///
+ /// Manifest to check.
+ /// A value indicating whether testing should be used.
+ public static bool UseTesting(PluginManifest manifest)
+ {
+ var configuration = Service.Get();
+
+ if (!configuration.DoPluginTest)
+ return false;
+
+ if (manifest.IsTestingExclusive)
+ return true;
+
+ var av = manifest.AssemblyVersion;
+ var tv = manifest.TestingAssemblyVersion;
+ var hasTv = tv != null;
+
+ if (hasTv)
+ {
+ return tv > av;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Gets a value indicating whether the given repo manifest should be visible to the user.
+ ///
+ /// Repo manifest.
+ /// If the manifest is visible.
+ public static bool IsManifestVisible(RemotePluginManifest manifest)
+ {
+ var configuration = Service.Get();
+
+ // Hidden by user
+ if (configuration.HiddenPluginInternalName.Contains(manifest.InternalName))
+ return false;
+
+ // Hidden by manifest
+ return !manifest.IsHide;
+ }
+
///
public void Dispose()
{
@@ -144,7 +220,7 @@ namespace Dalamud.Plugin.Internal
/// Set the list of repositories to use and downloads their contents.
/// Should be called when the Settings window has been updated or at instantiation.
///
- /// Whether the available plugins changed should be evented after.
+ /// Whether the available plugins changed event should be sent after.
/// A representing the asynchronous operation.
public async Task SetPluginReposFromConfigAsync(bool notify)
{
@@ -198,7 +274,7 @@ namespace Dalamud.Plugin.Internal
var manifest = LocalPluginManifest.Load(manifestFile);
- pluginDefs.Add(new(dllFile, manifest, false));
+ pluginDefs.Add(new PluginDef(dllFile, manifest, false));
}
}
@@ -225,7 +301,7 @@ namespace Dalamud.Plugin.Internal
// Manifests are not required for devPlugins. the Plugin type will handle any null manifests.
var manifestFile = LocalPluginManifest.GetManifestFile(dllFile);
var manifest = manifestFile.Exists ? LocalPluginManifest.Load(manifestFile) : null;
- devPluginDefs.Add(new(dllFile, manifest, true));
+ devPluginDefs.Add(new PluginDef(dllFile, manifest, true));
}
// Sort for load order - unloaded definitions have default priority of 0
@@ -235,9 +311,9 @@ namespace Dalamud.Plugin.Internal
// Dev plugins should load first.
pluginDefs.InsertRange(0, devPluginDefs);
- void LoadPlugins(IEnumerable pluginDefs)
+ void LoadPlugins(IEnumerable pluginDefsList)
{
- foreach (var pluginDef in pluginDefs)
+ foreach (var pluginDef in pluginDefsList)
{
try
{
@@ -260,7 +336,7 @@ namespace Dalamud.Plugin.Internal
var asyncPlugins = pluginDefs.Where(def => def.Manifest == null || def.Manifest.LoadPriority <= 0);
Task.Run(() => LoadPlugins(asyncPlugins))
- .ContinueWith(task =>
+ .ContinueWith(_ =>
{
this.PluginsReady = true;
this.NotifyInstalledPluginsChanged();
@@ -318,7 +394,7 @@ namespace Dalamud.Plugin.Internal
this.AvailablePlugins = this.Repos
.SelectMany(repo => repo.PluginMaster)
.Where(this.IsManifestEligible)
- .Where(this.IsManifestVisible)
+ .Where(IsManifestVisible)
.ToImmutableList();
if (notify)
@@ -412,7 +488,7 @@ namespace Dalamud.Plugin.Internal
var response = await Util.HttpClient.GetAsync(downloadUrl);
response.EnsureSuccessStatusCode();
- var outputDir = new DirectoryInfo(Path.Combine(this.pluginDirectory.FullName, repoManifest.InternalName, version.ToString()));
+ var outputDir = new DirectoryInfo(Path.Combine(this.pluginDirectory.FullName, repoManifest.InternalName, version?.ToString() ?? string.Empty));
try
{
@@ -568,7 +644,6 @@ namespace Dalamud.Plugin.Internal
{
// Out of date plugins get added so they can be updated.
Log.Information(ex, $"Plugin was outdated, adding anyways: {dllFile.Name}");
- // plugin.Disable(); // Don't disable, or it gets deleted next boot.
}
else
{
@@ -625,14 +700,12 @@ namespace Dalamud.Plugin.Internal
return version;
})
- .Where(version => version != null)
.ToArray();
if (versionDirs.Length == 0)
{
Log.Information($"No versions: cleaning up {pluginDir.FullName}");
pluginDir.Delete(true);
- continue;
}
else
{
@@ -675,7 +748,6 @@ namespace Dalamud.Plugin.Internal
{
Log.Information($"Inapplicable version: cleaning up {versionDir.FullName}");
versionDir.Delete(true);
- continue;
}
}
catch (Exception ex)
@@ -737,13 +809,12 @@ namespace Dalamud.Plugin.Internal
{
InternalName = plugin.Manifest.InternalName,
Name = plugin.Manifest.Name,
- Version = metadata.UseTesting
- ? metadata.UpdateManifest.TestingAssemblyVersion
- : metadata.UpdateManifest.AssemblyVersion,
+ Version = (metadata.UseTesting
+ ? metadata.UpdateManifest.TestingAssemblyVersion
+ : metadata.UpdateManifest.AssemblyVersion)!,
+ WasUpdated = true,
};
- updateStatus.WasUpdated = true;
-
if (!dryRun)
{
// Unload if loaded
@@ -836,88 +907,6 @@ namespace Dalamud.Plugin.Internal
plugin.Load(PluginLoadReason.Installer);
}
- ///
- /// Print to chat any plugin updates and whether they were successful.
- ///
- /// The list of updated plugin metadata.
- /// The header text to send to chat prior to any update info.
- public void PrintUpdatedPlugins(List updateMetadata, string header)
- {
- var chatGui = Service.Get();
-
- if (updateMetadata != null && updateMetadata.Count > 0)
- {
- chatGui.Print(header);
-
- foreach (var metadata in updateMetadata)
- {
- if (metadata.WasUpdated)
- {
- chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version));
- }
- else
- {
- chatGui.PrintChat(new XivChatEntry
- {
- Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version),
- Type = XivChatType.Urgent,
- });
- }
- }
- }
- }
-
- ///
- /// For a given manifest, determine if the testing version should be used over the normal version.
- /// The higher of the two versions is calculated after checking other settings.
- ///
- /// Manifest to check.
- /// A value indicating whether testing should be used.
- public bool UseTesting(PluginManifest manifest)
- {
- var configuration = Service.Get();
-
- if (!configuration.DoPluginTest)
- return false;
-
- if (manifest.IsTestingExclusive)
- return true;
-
- var av = manifest.AssemblyVersion;
- var tv = manifest.TestingAssemblyVersion;
- var hasAv = av != null;
- var hasTv = tv != null;
-
- if (hasAv && hasTv)
- {
- return tv > av;
- }
- else
- {
- return hasTv;
- }
- }
-
- ///
- /// Gets a value indicating whether the given repo manifest should be visible to the user.
- ///
- /// Repo manifest.
- /// If the manifest is visible.
- public bool IsManifestVisible(RemotePluginManifest manifest)
- {
- var configuration = Service.Get();
-
- // Hidden by user
- if (configuration.HiddenPluginInternalName.Contains(manifest.InternalName))
- return false;
-
- // Hidden by manifest
- if (manifest.IsHide)
- return false;
-
- return true;
- }
-
///
/// Gets a value indicating whether the given manifest is eligible for ANYTHING. These are hard
/// checks that should not allow installation or loading.
@@ -942,10 +931,7 @@ namespace Dalamud.Plugin.Internal
return false;
// Banned
- if (this.IsManifestBanned(manifest))
- return false;
-
- return true;
+ return !this.IsManifestBanned(manifest);
}
///
@@ -984,7 +970,7 @@ namespace Dalamud.Plugin.Internal
.Where(remoteManifest => plugin.Manifest.InternalName == remoteManifest.InternalName)
.Select(remoteManifest =>
{
- var useTesting = this.UseTesting(remoteManifest);
+ var useTesting = UseTesting(remoteManifest);
var candidateVersion = useTesting
? remoteManifest.TestingAssemblyVersion
: remoteManifest.AssemblyVersion;
@@ -998,7 +984,7 @@ namespace Dalamud.Plugin.Internal
if (updates.Count > 0)
{
var update = updates.Aggregate((t1, t2) => t1.candidateVersion > t2.candidateVersion ? t1 : t2);
- updatablePlugins.Add(new(plugin, update.remoteManifest, update.useTesting));
+ updatablePlugins.Add(new AvailablePluginUpdate(plugin, update.remoteManifest, update.useTesting));
}
}
@@ -1033,41 +1019,6 @@ namespace Dalamud.Plugin.Internal
}
}
- private struct BannedPlugin
- {
- [JsonProperty]
- public string Name { get; private set; }
-
- [JsonProperty]
- public Version AssemblyVersion { get; private set; }
-
- [JsonProperty]
- public string Reason { get; private set; }
- }
-
- private struct PluginDef
- {
- public PluginDef(FileInfo dllFile, LocalPluginManifest? manifest, bool isDev)
- {
- this.DllFile = dllFile;
- this.Manifest = manifest;
- this.IsDev = isDev;
- }
-
- public FileInfo DllFile { get; init; }
-
- public LocalPluginManifest? Manifest { get; init; }
-
- public bool IsDev { get; init; }
-
- public static int Sorter(PluginDef def1, PluginDef def2)
- {
- var prio1 = def1.Manifest?.LoadPriority ?? 0;
- var prio2 = def2.Manifest?.LoadPriority ?? 0;
- return prio2.CompareTo(prio1);
- }
- }
-
private static class Locs
{
public static string DalamudPluginUpdateSuccessful(string name, Version version) => Loc.Localize("DalamudPluginUpdateSuccessful", " 》 {0} updated to v{1}.").Format(name, version);
@@ -1162,7 +1113,7 @@ namespace Dalamud.Plugin.Internal
if (methodBase == null)
continue;
- yield return methodBase.Module.Assembly.FullName;
+ yield return methodBase.Module.Assembly.FullName!;
}
}
@@ -1171,37 +1122,14 @@ namespace Dalamud.Plugin.Internal
var targetType = typeof(PluginManager).Assembly.GetType();
var locationTarget = targetType.GetProperty(nameof(Assembly.Location))!.GetGetMethod();
- var locationPatch = typeof(PluginManager).GetMethod(nameof(PluginManager.AssemblyLocationPatch), BindingFlags.NonPublic | BindingFlags.Static);
+ var locationPatch = typeof(PluginManager).GetMethod(nameof(AssemblyLocationPatch), BindingFlags.NonPublic | BindingFlags.Static);
this.assemblyLocationMonoHook = new MonoMod.RuntimeDetour.Hook(locationTarget, locationPatch);
-#pragma warning disable SYSLIB0012 // Type or member is obsolete
- var codebaseTarget = targetType.GetProperty(nameof(Assembly.CodeBase)).GetGetMethod();
- var codebasePatch = typeof(PluginManager).GetMethod(nameof(PluginManager.AssemblyCodeBasePatch), BindingFlags.NonPublic | BindingFlags.Static);
+ #pragma warning disable CS0618
+ var codebaseTarget = targetType.GetProperty(nameof(Assembly.CodeBase))?.GetGetMethod();
+ #pragma warning restore CS0618
+ var codebasePatch = typeof(PluginManager).GetMethod(nameof(AssemblyCodeBasePatch), BindingFlags.NonPublic | BindingFlags.Static);
this.assemblyCodeBaseMonoHook = new MonoMod.RuntimeDetour.Hook(codebaseTarget, codebasePatch);
-#pragma warning restore SYSLIB0012 // Type or member is obsolete
- }
-
- internal record PluginPatchData
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// DLL file being loaded.
- public PluginPatchData(FileInfo dllFile)
- {
- this.Location = dllFile.FullName;
- this.CodeBase = new Uri(dllFile.FullName).AbsoluteUri;
- }
-
- ///
- /// Gets simulated Assembly.Location output.
- ///
- public string Location { get; }
-
- ///
- /// Gets simulated Assembly.CodeBase output.
- ///
- public string CodeBase { get; }
}
}
}
diff --git a/Dalamud/Plugin/Internal/Types/BannedPlugin.cs b/Dalamud/Plugin/Internal/Types/BannedPlugin.cs
new file mode 100644
index 000000000..1d5f956b3
--- /dev/null
+++ b/Dalamud/Plugin/Internal/Types/BannedPlugin.cs
@@ -0,0 +1,29 @@
+using System;
+
+using Newtonsoft.Json;
+
+namespace Dalamud.Plugin.Internal.Types;
+
+///
+/// Banned plugin version that is blocked from installation.
+///
+internal struct BannedPlugin
+{
+ ///
+ /// Gets plugin name.
+ ///
+ [JsonProperty]
+ public string Name { get; private set; }
+
+ ///
+ /// Gets plugin assembly version.
+ ///
+ [JsonProperty]
+ public Version AssemblyVersion { get; private set; }
+
+ ///
+ /// Gets reason for the ban.
+ ///
+ [JsonProperty]
+ public string Reason { get; private set; }
+}
diff --git a/Dalamud/Plugin/Internal/Types/PluginDef.cs b/Dalamud/Plugin/Internal/Types/PluginDef.cs
new file mode 100644
index 000000000..c5dbede0d
--- /dev/null
+++ b/Dalamud/Plugin/Internal/Types/PluginDef.cs
@@ -0,0 +1,50 @@
+using System.IO;
+
+namespace Dalamud.Plugin.Internal.Types;
+
+///
+/// Plugin Definition.
+///
+internal struct PluginDef
+{
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// plugin dll file.
+ /// plugin manifest.
+ /// plugin dev indicator.
+ public PluginDef(FileInfo dllFile, LocalPluginManifest? manifest, bool isDev)
+ {
+ this.DllFile = dllFile;
+ this.Manifest = manifest;
+ this.IsDev = isDev;
+ }
+
+ ///
+ /// Gets plugin DLL File.
+ ///
+ public FileInfo DllFile { get; init; }
+
+ ///
+ /// Gets plugin manifest.
+ ///
+ public LocalPluginManifest? Manifest { get; init; }
+
+ ///
+ /// Gets a value indicating whether plugin is a dev plugin.
+ ///
+ public bool IsDev { get; init; }
+
+ ///
+ /// Sort plugin definitions by priority.
+ ///
+ /// plugin definition 1 to compare.
+ /// plugin definition 2 to compare.
+ /// sort order.
+ public static int Sorter(PluginDef def1, PluginDef def2)
+ {
+ var priority1 = def1.Manifest?.LoadPriority ?? 0;
+ var priority2 = def2.Manifest?.LoadPriority ?? 0;
+ return priority2.CompareTo(priority1);
+ }
+}
diff --git a/Dalamud/Plugin/Internal/Types/PluginPatchData.cs b/Dalamud/Plugin/Internal/Types/PluginPatchData.cs
new file mode 100644
index 000000000..d95c1e62c
--- /dev/null
+++ b/Dalamud/Plugin/Internal/Types/PluginPatchData.cs
@@ -0,0 +1,27 @@
+using System;
+using System.IO;
+
+namespace Dalamud.Plugin.Internal.Types;
+
+internal record PluginPatchData
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// DLL file being loaded.
+ public PluginPatchData(FileSystemInfo dllFile)
+ {
+ this.Location = dllFile.FullName;
+ this.CodeBase = new Uri(dllFile.FullName).AbsoluteUri;
+ }
+
+ ///
+ /// Gets simulated Assembly.Location output.
+ ///
+ public string Location { get; }
+
+ ///
+ /// Gets simulated Assembly.CodeBase output.
+ ///
+ public string CodeBase { get; }
+}