Require an explicit launch path for mod registrations.

This also removes a workaround that allowed the current mod to be
registered even if it defined a bogus path. Uses of Game.ExternalMods
should therefore always use TryGetValue and correctly handle it
returning false.
This commit is contained in:
Paul Chote
2021-09-25 11:23:51 +01:00
committed by teinarss
parent 4275e87c57
commit 5d83706eae
3 changed files with 9 additions and 25 deletions

View File

@@ -191,7 +191,7 @@ namespace OpenRA
/// * Filename doesn't match internal key /// * Filename doesn't match internal key
/// * Fails to parse as a mod registration /// * Fails to parse as a mod registration
/// </summary> /// </summary>
internal void ClearInvalidRegistrations(ExternalMod activeMod, ModRegistration registration) internal void ClearInvalidRegistrations(ModRegistration registration)
{ {
var sources = new List<string>(); var sources = new List<string>();
if (registration.HasFlag(ModRegistration.System)) if (registration.HasFlag(ModRegistration.System))
@@ -206,7 +206,6 @@ namespace OpenRA
sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser)); sources.Add(Platform.GetSupportDir(SupportDirType.LegacyUser));
} }
var activeModKey = ExternalMod.MakeKey(activeMod);
foreach (var source in sources.Distinct()) foreach (var source in sources.Distinct())
{ {
var metadataPath = Path.Combine(source, "ModMetadata"); var metadataPath = Path.Combine(source, "ModMetadata");
@@ -222,13 +221,10 @@ namespace OpenRA
var m = FieldLoader.Load<ExternalMod>(yaml); var m = FieldLoader.Load<ExternalMod>(yaml);
modKey = ExternalMod.MakeKey(m); modKey = ExternalMod.MakeKey(m);
// Continue to the next entry if it is the active mod (even if the LaunchPath is bogus)
if (modKey == activeModKey)
continue;
// Continue to the next entry if this one is valid // Continue to the next entry if this one is valid
if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey && // HACK: Explicitly invalidate paths to OpenRA.dll to clean up bogus metadata files
!(activeMod != null && m.LaunchPath == activeMod.LaunchPath && m.Id == activeMod.Id && m.Version != activeMod.Version)) // that were created after the initial migration from .NET Framework to Core/5.
if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey && Path.GetExtension(m.LaunchPath) != ".dll")
continue; continue;
} }
catch (Exception e) catch (Exception e)

View File

@@ -407,19 +407,11 @@ namespace OpenRA
if (launchPath != null && launchPath.First() == '"' && launchPath.Last() == '"') if (launchPath != null && launchPath.First() == '"' && launchPath.Last() == '"')
launchPath = launchPath.Substring(1, launchPath.Length - 2); launchPath = launchPath.Substring(1, launchPath.Length - 2);
if (launchPath == null) // Metadata registration requires an explicit launch path
{ if (launchPath != null)
// When launching the assembly directly we must propagate the Engine.EngineDir argument if defined ExternalMods.Register(Mods[modID], launchPath, launchArgs, ModRegistration.User);
// Platform-specific launchers are expected to manage this internally.
launchPath = Assembly.GetEntryAssembly().Location;
if (!string.IsNullOrEmpty(engineDirArg))
launchArgs.Add("Engine.EngineDir=\"" + engineDirArg + "\"");
}
ExternalMods.Register(Mods[modID], launchPath, launchArgs, ModRegistration.User); ExternalMods.ClearInvalidRegistrations(ModRegistration.User);
if (ExternalMods.TryGetValue(ExternalMod.MakeKey(Mods[modID]), out var activeMod))
ExternalMods.ClearInvalidRegistrations(activeMod, ModRegistration.User);
} }
Console.WriteLine("External mods:"); Console.WriteLine("External mods:");

View File

@@ -32,11 +32,7 @@ namespace OpenRA.UtilityCommands
if (args[1] == "user" || args[1] == "both") if (args[1] == "user" || args[1] == "both")
type |= ModRegistration.User; type |= ModRegistration.User;
var mods = new ExternalMods(); new ExternalMods().ClearInvalidRegistrations(type);
ExternalMod activeMod = null;
mods.TryGetValue(ExternalMod.MakeKey(utility.ModData.Manifest), out activeMod);
mods.ClearInvalidRegistrations(activeMod, type);
} }
} }
} }