Skip to content

Commit

Permalink
feat: refactor safe mode, add "no third party" mode for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
goaaats committed Jul 13, 2022
1 parent f501534 commit fc5d8a8
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 25 deletions.
5 changes: 5 additions & 0 deletions Dalamud.Injector/EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ public static void Main(int argc, IntPtr argvPtr)
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)
Expand Down Expand Up @@ -322,6 +324,8 @@ private static DalamudStartInfo ExtractAndInitializeStartInfoFromArguments(Dalam
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;
Expand Down Expand Up @@ -362,6 +366,7 @@ private static int ProcessHelpCommand(List<string> args, string? particularComma
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;
}
Expand Down
12 changes: 12 additions & 0 deletions Dalamud/DalamudStartInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public DalamudStartInfo(DalamudStartInfo other)
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;
Expand Down Expand Up @@ -88,6 +90,16 @@ public DalamudStartInfo(DalamudStartInfo other)
/// </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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,11 @@ private void DrawUpdatePluginsButton()

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);
}
Expand Down Expand Up @@ -1039,12 +1043,6 @@ private bool DrawPluginListLoading()
{
var pluginManager = Service<PluginManager>.Get();

if (pluginManager.SafeMode)
{
ImGui.Text(Locs.TabBody_SafeMode);
return false;
}

var ready = pluginManager.PluginsReady && pluginManager.ReposReady;

if (!ready)
Expand Down Expand Up @@ -1186,6 +1184,12 @@ private bool DrawPluginCollapsingHeader(string label, LocalPlugin? plugin, Plugi
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);
Expand Down Expand Up @@ -1339,7 +1343,11 @@ private void DrawAvailablePlugin(RemotePluginManifest manifest, int index)
? $"{manifest.TestingAssemblyVersion}"
: $"{manifest.AssemblyVersion}";

if (disabled)
if (pluginManager.SafeMode)
{
ImGuiComponents.DisabledButton(Locs.PluginButton_SafeMode);
}
else if (disabled)
{
ImGuiComponents.DisabledButton(Locs.PluginButton_InstallVersion(versionString));
}
Expand Down Expand Up @@ -1463,14 +1471,14 @@ private void DrawInstalledPlugin(LocalPlugin plugin, int index, bool showInstall
}

// 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;
Expand Down Expand Up @@ -1716,7 +1724,12 @@ private void DrawPluginControlButton(LocalPlugin plugin)
}
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);
}
Expand Down Expand Up @@ -2323,6 +2336,8 @@ private static class Locs

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);

Expand All @@ -2340,6 +2355,8 @@ public static string PluginBody_BannedReason(string message) =>

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
Expand Down Expand Up @@ -2388,6 +2405,8 @@ public static string PluginBody_BannedReason(string message) =>

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!");
Expand Down
24 changes: 10 additions & 14 deletions Dalamud/Plugin/Internal/PluginManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ private PluginManager()
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;
Expand Down Expand Up @@ -281,12 +281,6 @@ public async Task SetPluginReposFromConfigAsync(bool notify)
/// </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>();

Expand Down Expand Up @@ -504,12 +498,6 @@ public void RefilterPluginMasters(bool notify = true)
/// </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();

Expand Down Expand Up @@ -753,6 +741,14 @@ public async Task<LocalPlugin> LoadPluginAsync(FileInfo dllFile, LocalPluginMani
// 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 _);
Expand Down Expand Up @@ -1064,7 +1060,7 @@ public bool IsManifestEligible(PluginManifest manifest)
/// <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);
}

Expand Down
24 changes: 24 additions & 0 deletions Dalamud/Plugin/Internal/Types/LocalPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ public async Task LoadAsync(PluginLoadReason reason, bool reloading = false)
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}");

Expand Down Expand Up @@ -553,6 +556,27 @@ public void Enable()
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>
Expand Down

0 comments on commit fc5d8a8

Please sign in to comment.