feat: refactor safe mode, add "no third party" mode for testing

This commit is contained in:
goat 2022-07-13 19:43:59 +02:00
parent f501534739
commit fc5d8a8c86
No known key found for this signature in database
GPG key ID: 7773BB5B43BA52E5
5 changed files with 81 additions and 25 deletions

View file

@ -91,6 +91,8 @@ namespace Dalamud.Injector
args.Remove("--etw");
args.Remove("--veh");
args.Remove("--veh-full");
args.Remove("--no-plugin");
args.Remove("--no-3rd-plugin");
var mainCommand = args[1].ToLowerInvariant();
if (mainCommand.Length > 0 && mainCommand.Length <= 6 && "inject"[..mainCommand.Length] == mainCommand)
@ -322,6 +324,8 @@ namespace Dalamud.Injector
startInfo.BootWaitMessageBox |= args.Contains("--msgbox3") ? 4 : 0;
startInfo.BootVehEnabled = args.Contains("--veh");
startInfo.BootVehFull = args.Contains("--veh-full");
startInfo.NoLoadPlugins = args.Contains("--no-plugin");
startInfo.NoLoadThirdPartyPlugins = args.Contains("--no-third-plugin");
// startInfo.BootUnhookDlls = new List<string>() { "kernel32.dll", "ntdll.dll", "user32.dll" };
return startInfo;
@ -362,6 +366,7 @@ namespace Dalamud.Injector
Console.WriteLine("Enable ETW:\t[--etw]");
Console.WriteLine("Enable VEH:\t[--veh], [--veh-full]");
Console.WriteLine("Show messagebox:\t[--msgbox1], [--msgbox2], [--msgbox3]");
Console.WriteLine("No plugins:\t[--no-plugin] [--no-3rd-plugin]");
return 0;
}

View file

@ -34,6 +34,8 @@ namespace Dalamud
this.Language = other.Language;
this.GameVersion = other.GameVersion;
this.DelayInitializeMs = other.DelayInitializeMs;
this.NoLoadPlugins = other.NoLoadPlugins;
this.NoLoadThirdPartyPlugins = other.NoLoadThirdPartyPlugins;
this.BootLogPath = other.BootLogPath;
this.BootShowConsole = other.BootShowConsole;
this.BootDisableFallbackConsole = other.BootDisableFallbackConsole;
@ -88,6 +90,16 @@ namespace Dalamud
/// </summary>
public int DelayInitializeMs { get; set; }
/// <summary>
/// Gets or sets a value indicating whether no plugins should be loaded.
/// </summary>
public bool NoLoadPlugins { get; set; }
/// <summary>
/// Gets or sets a value indicating whether no third-party plugins should be loaded.
/// </summary>
public bool NoLoadThirdPartyPlugins { get; set; }
/// <summary>
/// Gets or sets the path the boot log file is supposed to be written to.
/// </summary>

View file

@ -317,7 +317,11 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
var ready = pluginManager.PluginsReady && pluginManager.ReposReady;
if (!ready || this.updateStatus == OperationStatus.InProgress || this.installStatus == OperationStatus.InProgress)
if (pluginManager.SafeMode)
{
ImGuiComponents.DisabledButton(Locs.FooterButton_UpdateSafeMode);
}
else if (!ready || this.updateStatus == OperationStatus.InProgress || this.installStatus == OperationStatus.InProgress)
{
ImGuiComponents.DisabledButton(Locs.FooterButton_UpdatePlugins);
}
@ -1039,12 +1043,6 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
{
var pluginManager = Service<PluginManager>.Get();
if (pluginManager.SafeMode)
{
ImGui.Text(Locs.TabBody_SafeMode);
return false;
}
var ready = pluginManager.PluginsReady && pluginManager.ReposReady;
if (!ready)
@ -1186,6 +1184,12 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
ImGui.TextWrapped(Locs.PluginBody_Orphaned);
ImGui.PopStyleColor();
}
else if (plugin != null && !plugin.CheckPolicy())
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGui.TextWrapped(Locs.PluginBody_Policy);
ImGui.PopStyleColor();
}
else if (plugin is { State: PluginState.LoadError or PluginState.DependencyResolutionFailed }) // Load failed warning
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
@ -1339,7 +1343,11 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
? $"{manifest.TestingAssemblyVersion}"
: $"{manifest.AssemblyVersion}";
if (disabled)
if (pluginManager.SafeMode)
{
ImGuiComponents.DisabledButton(Locs.PluginButton_SafeMode);
}
else if (disabled)
{
ImGuiComponents.DisabledButton(Locs.PluginButton_InstallVersion(versionString));
}
@ -1463,14 +1471,14 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
}
// Disabled
if (plugin.IsDisabled)
if (plugin.IsDisabled || !plugin.CheckPolicy())
{
label += Locs.PluginTitleMod_Disabled;
trouble = true;
}
// Load error
if (plugin.State is PluginState.LoadError or PluginState.DependencyResolutionFailed)
if (plugin.State is PluginState.LoadError or PluginState.DependencyResolutionFailed && plugin.CheckPolicy())
{
label += Locs.PluginTitleMod_LoadError;
trouble = true;
@ -1716,7 +1724,12 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
}
else if (plugin.State == PluginState.Loaded || plugin.State == PluginState.LoadError || plugin.State == PluginState.DependencyResolutionFailed)
{
if (disabled)
// TODO: We should draw the trash can button for policy-blocked plugins in safe mode, so plugins can be deleted
if (pluginManager.SafeMode)
{
ImGuiComponents.DisabledButton(Locs.PluginButton_SafeMode);
}
else if (disabled)
{
ImGuiComponents.DisabledButton(Locs.PluginButton_Disable);
}
@ -2323,6 +2336,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
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.");
public static string PluginBody_Policy => Loc.Localize("InstallerPolicyPluginBody ", "Plugin loads for this type of plugin were manually disabled.");
public static string PluginBody_BannedReason(string message) =>
Loc.Localize("InstallerBannedPluginBodyReason ", "This plugin was automatically disabled: {0}").Format(message);
@ -2340,6 +2355,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
public static string PluginButton_Unload => Loc.Localize("InstallerUnload", "Unload");
public static string PluginButton_SafeMode => Loc.Localize("InstallerSafeModeButton", "Can't change in safe mode");
#endregion
#region Plugin button tooltips
@ -2388,6 +2405,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
public static string FooterButton_UpdatePlugins => Loc.Localize("InstallerUpdatePlugins", "Update plugins");
public static string FooterButton_UpdateSafeMode => Loc.Localize("InstallerUpdateSafeMode", "Can't update in safe mode");
public static string FooterButton_InProgress => Loc.Localize("InstallerInProgress", "Install in progress...");
public static string FooterButton_NoUpdates => Loc.Localize("InstallerNoUpdates", "No updates found!");

View file

@ -68,7 +68,7 @@ internal partial class PluginManager : IDisposable, IServiceType
if (!this.devPluginDirectory.Exists)
this.devPluginDirectory.Create();
this.SafeMode = EnvironmentConfiguration.DalamudNoPlugins || this.configuration.PluginSafeMode;
this.SafeMode = EnvironmentConfiguration.DalamudNoPlugins || this.configuration.PluginSafeMode || this.startInfo.NoLoadPlugins;
if (this.SafeMode)
{
this.configuration.PluginSafeMode = false;
@ -281,12 +281,6 @@ internal partial class PluginManager : IDisposable, IServiceType
/// </remarks>
public void LoadAllPlugins()
{
if (this.SafeMode)
{
Log.Information("PluginSafeMode was enabled, not loading any plugins.");
return;
}
var pluginDefs = new List<PluginDef>();
var devPluginDefs = new List<PluginDef>();
@ -504,12 +498,6 @@ internal partial class PluginManager : IDisposable, IServiceType
/// </summary>
public void ScanDevPlugins()
{
if (this.SafeMode)
{
Log.Information("PluginSafeMode was enabled, not scanning any dev plugins.");
return;
}
if (!this.devPluginDirectory.Exists)
this.devPluginDirectory.Create();
@ -753,6 +741,14 @@ internal partial class PluginManager : IDisposable, IServiceType
// NOTE(goat): This can't work - plugins don't "unload" if they fail to load.
// plugin.Disable(); // Disable here, otherwise you can't enable+load later
}
else if (!plugin.CheckPolicy())
{
// During boot load, plugins always get added to the list so they can be fiddled with in the UI
Log.Information(ex, $"Plugin not loaded due to policy, adding anyways: {dllFile.Name}");
// NOTE(goat): This can't work - plugins don't "unload" if they fail to load.
// plugin.Disable(); // Disable here, otherwise you can't enable+load later
}
else
{
PluginLocations.Remove(plugin.AssemblyName?.FullName ?? string.Empty, out _);
@ -1064,7 +1060,7 @@ internal partial class PluginManager : IDisposable, IServiceType
/// <returns>A value indicating whether the plugin/manifest has been banned.</returns>
public bool IsManifestBanned(PluginManifest manifest)
{
return !configuration.LoadBannedPlugins && this.bannedPlugins.Any(ban => (ban.Name == manifest.InternalName || ban.Name == Hash.GetStringSha256Hash(manifest.InternalName))
return !this.configuration.LoadBannedPlugins && this.bannedPlugins.Any(ban => (ban.Name == manifest.InternalName || ban.Name == Hash.GetStringSha256Hash(manifest.InternalName))
&& ban.AssemblyVersion >= manifest.AssemblyVersion);
}

View file

@ -311,6 +311,9 @@ internal class LocalPlugin : IDisposable
if (this.IsOrphaned)
throw new InvalidPluginOperationException($"Plugin {this.Name} had no associated repo.");
if (!this.CheckPolicy())
throw new InvalidPluginOperationException("Plugin was not loaded as per policy");
this.State = PluginState.Loading;
Log.Information($"Loading {this.DllFile.Name}");
@ -553,6 +556,27 @@ internal class LocalPlugin : IDisposable
this.SaveManifest();
}
/// <summary>
/// Check if anything forbids this plugin from loading.
/// </summary>
/// <returns>Whether or not this plugin shouldn't load.</returns>
public bool CheckPolicy()
{
var startInfo = Service<DalamudStartInfo>.Get();
var manager = Service<PluginManager>.Get();
if (startInfo.NoLoadPlugins)
return false;
if (startInfo.NoLoadThirdPartyPlugins && this.Manifest.IsThirdParty)
return false;
if (manager.SafeMode)
return false;
return true;
}
/// <summary>
/// Disable this plugin, must be unloaded first.
/// </summary>