Remember trusted ext. tools

This commit is contained in:
YoshiRulz 2022-11-24 18:09:46 +10:00
parent f9ac3c4b32
commit 4566b744d9
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
4 changed files with 88 additions and 20 deletions

View File

@ -358,5 +358,7 @@ namespace BizHawk.Client.Common
public int OSDMessageDuration { get; set; } = 2; public int OSDMessageDuration { get; set; } = 2;
public Queue<string> RecentCores { get; set; } = new(); public Queue<string> RecentCores { get; set; } = new();
public Dictionary<string, string> TrustedExtTools { get; set; } = new();
} }
} }

View File

@ -1202,20 +1202,27 @@ namespace BizHawk.Client.EmuHawk
private void ExternalToolMenuItem_DropDownOpening(object sender, EventArgs e) private void ExternalToolMenuItem_DropDownOpening(object sender, EventArgs e)
{ {
ExternalToolMenuItem.DropDownItems.Clear(); ExternalToolMenuItem.DropDownItems.Clear();
ExternalToolMenuItem.DropDownItems.AddRange(ExtToolManager.ToolStripMenu.Cast<ToolStripItem>().ToArray());
foreach (var item in ExtToolManager.ToolStripMenu)
{
if (item.Enabled && item.Tag is ValueTuple<string, string> tuple)
{
item.Click += (_, _) => Tools.LoadExternalToolForm(tuple.Item1, tuple.Item2);
}
ExternalToolMenuItem.DropDownItems.Add(item);
}
if (ExternalToolMenuItem.DropDownItems.Count == 0) if (ExternalToolMenuItem.DropDownItems.Count == 0)
{ {
ExternalToolMenuItem.DropDownItems.Add("None"); ExternalToolMenuItem.DropDownItems.Add("None");
} }
if (Config.TrustedExtTools.Count is 0) return;
ExternalToolMenuItem.DropDownItems.Add(new ToolStripSeparatorEx());
ToolStripMenuItemEx forgetTrustedItem = new() { Text = "Forget trusted tools" };
forgetTrustedItem.Click += (_, _) =>
{
if (this.ModalMessageBox2(
caption: "Forget trusted ext. tools?",
text: "This will cause the warning about running third-party code to show again for all the ext. tools you've previously loaded.\n" +
"(If a tool has been loaded this session, the warning may not appear until EmuHawk is restarted.)",
useOKCancel: true))
{
Config.TrustedExtTools.Clear();
}
};
ExternalToolMenuItem.DropDownItems.Add(forgetTrustedItem);
} }
private void ToolBoxMenuItem_Click(object sender, EventArgs e) private void ToolBoxMenuItem_Click(object sender, EventArgs e)

View File

@ -450,7 +450,13 @@ namespace BizHawk.Client.EmuHawk
: null : null
); );
ExtToolManager = new ExternalToolManager(Config.PathEntries, () => (Emulator.SystemId, Game.Hash)); ExtToolManager = new(
Config,
() => (Emulator.SystemId, Game.Hash),
(toolPath, customFormTypeName, skipExtToolWarning) => Tools!.LoadExternalToolForm(
toolPath: toolPath,
customFormTypeName: customFormTypeName,
skipExtToolWarning: skipExtToolWarning) is not null);
Tools = new ToolManager(this, Config, DisplayManager, ExtToolManager, InputManager, Emulator, MovieSession, Game); Tools = new ToolManager(this, Config, DisplayManager, ExtToolManager, InputManager, Emulator, MovieSession, Game);
// TODO GL - move these event handlers somewhere less obnoxious line in the On* overrides // TODO GL - move these event handlers somewhere less obnoxious line in the On* overrides
@ -2956,7 +2962,7 @@ namespace BizHawk.Client.EmuHawk
InitControls(); // rebind hotkeys InitControls(); // rebind hotkeys
InputManager.SyncControls(Emulator, MovieSession, Config); InputManager.SyncControls(Emulator, MovieSession, Config);
Tools.Restart(Config, Emulator, Game); Tools.Restart(Config, Emulator, Game);
ExtToolManager.Restart(Config.PathEntries); ExtToolManager.Restart(Config);
Sound.Config = Config; Sound.Config = Config;
DisplayManager.UpdateGlobals(Config, Emulator); DisplayManager.UpdateGlobals(Config, Emulator);
AddOnScreenMessage($"Config file loaded: {iniPath}"); AddOnScreenMessage($"Config file loaded: {iniPath}");

View File

@ -14,9 +14,51 @@ namespace BizHawk.Client.EmuHawk
{ {
public sealed class ExternalToolManager public sealed class ExternalToolManager
{ {
public struct MenuItemInfo
{
private readonly string _asmChecksum;
private readonly string _asmFilename;
private readonly string _entryPointTypeName;
private readonly ExternalToolManager _extToolMan;
private bool _skipExtToolWarning;
public MenuItemInfo(
ExternalToolManager extToolMan,
string asmChecksum,
string asmFilename,
string entryPointTypeName)
{
_asmChecksum = asmChecksum;
_asmFilename = asmFilename;
_entryPointTypeName = entryPointTypeName;
_extToolMan = extToolMan;
_skipExtToolWarning = _extToolMan._config.TrustedExtTools.TryGetValue(_asmFilename, out var s) && s == _asmChecksum;
}
public void TryLoad()
{
var success = _extToolMan._loadCallback(
/*toolPath:*/ _asmFilename,
/*customFormTypeName:*/ _entryPointTypeName,
/*skipExtToolWarning:*/ _skipExtToolWarning);
if (!success || _skipExtToolWarning) return;
_skipExtToolWarning = true;
_extToolMan._config.TrustedExtTools[_asmFilename] = _asmChecksum;
}
}
private Config _config;
private readonly Func<(string SysID, string Hash)> _getLoadedRomInfoCallback; private readonly Func<(string SysID, string Hash)> _getLoadedRomInfoCallback;
private PathEntryCollection _paths; private readonly Func<string, string, bool, bool> _loadCallback;
private PathEntryCollection _paths
=> _config.PathEntries;
private FileSystemWatcher DirectoryMonitor; private FileSystemWatcher DirectoryMonitor;
@ -24,15 +66,19 @@ namespace BizHawk.Client.EmuHawk
internal readonly IList<string> PossibleExtToolTypeNames = new List<string>(); internal readonly IList<string> PossibleExtToolTypeNames = new List<string>();
public ExternalToolManager(PathEntryCollection paths, Func<(string SysID, string Hash)> getLoadedRomInfoCallback) public ExternalToolManager(
Config config,
Func<(string SysID, string Hash)> getLoadedRomInfoCallback,
Func<string, string, bool, bool> loadCallback)
{ {
_getLoadedRomInfoCallback = getLoadedRomInfoCallback; _getLoadedRomInfoCallback = getLoadedRomInfoCallback;
Restart(paths); _loadCallback = loadCallback;
Restart(config);
} }
public void Restart(PathEntryCollection paths) public void Restart(Config config)
{ {
_paths = paths; _config = config;
if (DirectoryMonitor != null) if (DirectoryMonitor != null)
{ {
DirectoryMonitor.Created -= DirectoryMonitor_Created; DirectoryMonitor.Created -= DirectoryMonitor_Created;
@ -65,7 +111,7 @@ namespace BizHawk.Client.EmuHawk
/// <summary>Generates a <see cref="ToolStripMenuItem"/> from an assembly at <paramref name="fileName"/> containing an external tool.</summary> /// <summary>Generates a <see cref="ToolStripMenuItem"/> from an assembly at <paramref name="fileName"/> containing an external tool.</summary>
/// <returns> /// <returns>
/// a <see cref="ToolStripMenuItem"/> with its <see cref="ToolStripItem.Tag"/> containing a <c>(string, string)</c>; /// a <see cref="ToolStripMenuItem"/> with its <see cref="ToolStripItem.Tag"/> containing a <see cref="MenuItemInfo"/>;
/// the first is the assembly path (<paramref name="fileName"/>) and the second is the <see cref="Type.FullName"/> of the entry point form's type /// the first is the assembly path (<paramref name="fileName"/>) and the second is the <see cref="Type.FullName"/> of the entry point form's type
/// </returns> /// </returns>
private ToolStripMenuItem GenerateToolTipFromFileName(string fileName) private ToolStripMenuItem GenerateToolTipFromFileName(string fileName)
@ -79,7 +125,8 @@ namespace BizHawk.Client.EmuHawk
try try
{ {
if (!OSTailoredCode.IsUnixHost) MotWHack.RemoveMOTW(fileName); if (!OSTailoredCode.IsUnixHost) MotWHack.RemoveMOTW(fileName);
var externalToolFile = Assembly.LoadFrom(fileName); var asmBytes = File.ReadAllBytes(fileName);
var externalToolFile = Assembly.Load(asmBytes);
var entryPoint = externalToolFile.GetTypes() var entryPoint = externalToolFile.GetTypes()
.SingleOrDefault(t => typeof(IExternalToolForm).IsAssignableFrom(t) && t.GetCustomAttributes().OfType<ExternalToolAttribute>().Any()); .SingleOrDefault(t => typeof(IExternalToolForm).IsAssignableFrom(t) && t.GetCustomAttributes().OfType<ExternalToolAttribute>().Any());
if (entryPoint == null) throw new ExternalToolAttribute.MissingException(); if (entryPoint == null) throw new ExternalToolAttribute.MissingException();
@ -102,7 +149,13 @@ namespace BizHawk.Client.EmuHawk
if (rawIcon != null) item.Image = new Bitmap(rawIcon); if (rawIcon != null) item.Image = new Bitmap(rawIcon);
} }
item.Text = toolAttribute.Name; item.Text = toolAttribute.Name;
item.Tag = (externalToolFile.Location, entryPoint.FullName); // Tag set => no errors (show custom icon even when disabled) MenuItemInfo menuItemInfo = new(
this,
asmChecksum: SHA1Checksum.ComputePrefixedHex(asmBytes),
asmFilename: fileName,
entryPointTypeName: entryPoint.FullName);
item.Tag = menuItemInfo;
item.Click += (_, _) => menuItemInfo.TryLoad();
PossibleExtToolTypeNames.Add(entryPoint.AssemblyQualifiedName); PossibleExtToolTypeNames.Add(entryPoint.AssemblyQualifiedName);
if (applicabilityAttrs.Count == 1) if (applicabilityAttrs.Count == 1)
{ {