Rework stale ExternalMod metadata clearing.

This commit is contained in:
Paul Chote
2017-06-28 23:51:19 +00:00
committed by reaperrr
parent b30cfe4ada
commit 372d940936
2 changed files with 53 additions and 30 deletions

View File

@@ -53,7 +53,7 @@ namespace OpenRA
try
{
var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
LoadMod(yaml);
LoadMod(yaml, path);
}
catch (Exception e)
{
@@ -63,7 +63,7 @@ namespace OpenRA
}
}
void LoadMod(MiniYaml yaml)
void LoadMod(MiniYaml yaml, string path = null)
{
var mod = FieldLoader.Load<ExternalMod>(yaml);
var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon");
@@ -74,7 +74,10 @@ namespace OpenRA
mod.Icon = sheetBuilder.Add(bitmap);
}
mods[ExternalMod.MakeKey(mod)] = mod;
// Avoid possibly overwriting a valid mod with an obviously bogus one
var key = ExternalMod.MakeKey(mod);
if (File.Exists(mod.LaunchPath) && (path == null || Path.GetFileNameWithoutExtension(path) == key))
mods[key] = mod;
}
internal void Register(Manifest mod, string launchPath)
@@ -113,29 +116,50 @@ namespace OpenRA
}
catch (Exception e)
{
Log.Write("debug", "Failed to register currrent mod metadata");
Log.Write("debug", "Failed to register current mod metadata");
Log.Write("debug", e.ToString());
}
}
/// <summary>
/// Removes invalid mod registrations:
/// * LaunchPath no longer exists
/// * LaunchPath and mod id matches the active mod, but the version is different
/// * Filename doesn't match internal key
/// * Fails to parse as a mod registration
/// </summary>
internal void ClearInvalidRegistrations(ExternalMod activeMod)
{
var metadataPath = Platform.ResolvePath(Path.Combine("^", "ModMetadata"));
foreach (var path in Directory.GetFiles(metadataPath, "*.yaml"))
{
string modKey = null;
try
{
var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
var m = FieldLoader.Load<ExternalMod>(yaml);
modKey = ExternalMod.MakeKey(m);
// Continue to the next entry if this one is valid
if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey &&
!(activeMod != null && m.LaunchPath == activeMod.LaunchPath && m.Id == activeMod.Id && m.Version != activeMod.Version))
continue;
}
catch (Exception e)
{
Log.Write("debug", "Failed to parse mod metadata file '{0}'", path);
Log.Write("debug", e.ToString());
}
// Clean up stale mod registrations:
// - LaunchPath no longer exists (uninstalled)
// - LaunchPath and mod match the current mod, but version differs (newer version installed on top)
List<string> toRemove = null;
foreach (var kv in mods)
{
var k = kv.Key;
var m = kv.Value;
if (!File.Exists(m.LaunchPath) || (m.LaunchPath == launchPath && m.Id == mod.Id && k != key))
{
Log.Write("debug", "Removing stale mod metadata entry '{0}'", k);
if (toRemove == null)
toRemove = new List<string>();
// Remove from the ingame mod switcher
if (Path.GetFileNameWithoutExtension(path) == modKey)
mods.Remove(modKey);
toRemove.Add(k);
var path = Path.Combine(supportPath, k + ".yaml");
// Remove stale or corrupted metadata
try
{
File.Delete(path);
Log.Write("debug", "Removed invalid mod metadata file '{0}'", path);
}
catch (Exception e)
{
@@ -145,11 +169,6 @@ namespace OpenRA
}
}
if (toRemove != null)
foreach (var r in toRemove)
mods.Remove(r);
}
public ExternalMod this[string key] { get { return mods[key]; } }
public int Count { get { return mods.Count; } }
public ICollection<string> Keys { get { return mods.Keys; } }

View File

@@ -351,6 +351,10 @@ namespace OpenRA
launchPath = launchPath.Substring(1, launchPath.Length - 2);
ExternalMods.Register(Mods[modID], launchPath);
ExternalMod activeMod;
if (ExternalMods.TryGetValue(ExternalMod.MakeKey(Mods[modID]), out activeMod))
ExternalMods.ClearInvalidRegistrations(activeMod);
}
Console.WriteLine("External mods:");