diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs
index 0381164c9..f3f2564af 100644
--- a/Dalamud/Interface/Internal/DalamudInterface.cs
+++ b/Dalamud/Interface/Internal/DalamudInterface.cs
@@ -1012,6 +1012,11 @@ internal class DalamudInterface : IInternalDisposableService
pluginManager.LoadBannedPlugins = !pluginManager.LoadBannedPlugins;
}
+ if (pluginManager.SafeMode && ImGui.MenuItem("Disable Safe Mode"))
+ {
+ pluginManager.SafeMode = false;
+ }
+
ImGui.Separator();
ImGui.MenuItem("API Level:" + PluginManager.DalamudApiLevel, false);
ImGui.MenuItem("Loaded plugins:" + pluginManager.InstalledPlugins.Count(), false);
diff --git a/Dalamud/Logging/Internal/ModuleLog.cs b/Dalamud/Logging/Internal/ModuleLog.cs
index bcbb6e2b1..bb5af4ffe 100644
--- a/Dalamud/Logging/Internal/ModuleLog.cs
+++ b/Dalamud/Logging/Internal/ModuleLog.cs
@@ -1,5 +1,6 @@
using Serilog;
using Serilog.Core;
+using Serilog.Core.Enrichers;
using Serilog.Events;
namespace Dalamud.Logging.Internal;
@@ -11,7 +12,7 @@ public class ModuleLog
{
private readonly string moduleName;
private readonly ILogger moduleLogger;
-
+
// FIXME (v9): Deprecate this class in favor of using contextualized ILoggers with proper formatting.
// We can keep this class around as a Serilog helper, but ModuleLog should no longer be a returned
// type, instead returning a (prepared) ILogger appropriately.
@@ -27,6 +28,28 @@ public class ModuleLog
this.moduleLogger = Log.ForContext("Dalamud.ModuleName", this.moduleName);
}
+ ///
+ /// Initializes a new instance of the class.
+ /// This class will properly attach SourceContext and other attributes per Serilog standards.
+ ///
+ /// The type of the class this logger is for.
+ public ModuleLog(Type type)
+ {
+ this.moduleName = type.Name;
+ this.moduleLogger = Log.ForContext(
+ [
+ new PropertyEnricher(Constants.SourceContextPropertyName, type.FullName),
+ new PropertyEnricher("Dalamud.ModuleName", this.moduleName)
+ ]);
+ }
+
+ ///
+ /// Helper method to create a new instance based on a type.
+ ///
+ /// The class to create this ModuleLog for.
+ /// Returns a ModuleLog with name set.
+ internal static ModuleLog Create() => new(typeof(T));
+
///
/// Log a templated verbose message to the in-game debug log.
///
diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index 7a05a7549..5cab004ed 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -48,7 +48,7 @@ internal class PluginManager : IInternalDisposableService
///
public const int PluginWaitBeforeFreeDefault = 1000; // upped from 500ms, seems more stable
- private static readonly ModuleLog Log = new("PLUGINM");
+ private static readonly ModuleLog Log = ModuleLog.Create();
private readonly object pluginListLock = new();
private readonly DirectoryInfo pluginDirectory;
@@ -243,9 +243,9 @@ internal class PluginManager : IInternalDisposableService
public bool ReposReady { get; private set; }
///
- /// Gets a value indicating whether the plugin manager started in safe mode.
+ /// Gets or sets a value indicating whether the plugin manager started in safe mode.
///
- public bool SafeMode { get; init; }
+ public bool SafeMode { get; set; }
///
/// Gets the object used when initializing plugins.
diff --git a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
index 43bba0a5b..a86a39905 100644
--- a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
+++ b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs
@@ -30,7 +30,7 @@ internal class LocalPlugin : IAsyncDisposable
#pragma warning disable SA1401
protected LocalPluginManifest manifest;
#pragma warning restore SA1401
-
+
private static readonly ModuleLog Log = new("LOCALPLUGIN");
private readonly FileInfo manifestFile;
@@ -314,7 +314,7 @@ internal class LocalPlugin : IAsyncDisposable
this.State = PluginState.Loading;
Log.Information($"Loading {this.DllFile.Name}");
-
+
this.EnsureLoader();
if (this.DllFile.DirectoryName != null &&
@@ -413,7 +413,7 @@ internal class LocalPlugin : IAsyncDisposable
if (ex is not InvalidPluginOperationException)
this.State = PluginState.LoadError;
- // If a precondition fails, don't record it as an error, as it isn't really.
+ // If a precondition fails, don't record it as an error, as it isn't really.
if (ex is PluginPreconditionFailedException)
Log.Warning(ex.Message);
else
@@ -510,9 +510,6 @@ internal class LocalPlugin : IAsyncDisposable
var startInfo = Service.Get().StartInfo;
var manager = Service.Get();
- if (startInfo.NoLoadPlugins)
- return false;
-
if (startInfo.NoLoadThirdPartyPlugins && this.manifest.IsThirdParty)
return false;
@@ -556,7 +553,7 @@ internal class LocalPlugin : IAsyncDisposable
///
/// Why it should be saved.
protected void SaveManifest(string reason) => this.manifest.Save(this.manifestFile, reason);
-
+
///
/// Called before a plugin is reloaded.
///
@@ -595,7 +592,7 @@ internal class LocalPlugin : IAsyncDisposable
// but plugins may load other versions of assemblies that Dalamud depends on.
config.SharedAssemblies.Add((typeof(EntryPoint).Assembly.GetName(), false));
config.SharedAssemblies.Add((typeof(Common.DalamudStartInfo).Assembly.GetName(), false));
-
+
// Pin Lumina since we expose it as an API surface. Before anyone removes this again, please see #1598.
// Changes to Lumina should be upstreamed if feasible, and if there is a desire to re-add unpinned Lumina we
// will need to put this behind some kind of feature flag somewhere.
@@ -607,7 +604,7 @@ internal class LocalPlugin : IAsyncDisposable
{
if (this.loader != null)
return;
-
+
try
{
this.loader = PluginLoader.CreateFromAssemblyFile(this.DllFile.FullName, SetupLoaderConfig);