Remember trusted ext. tools
This commit is contained in:
parent
f9ac3c4b32
commit
4566b744d9
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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}");
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue