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 try
{ {
var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value; var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
LoadMod(yaml); LoadMod(yaml, path);
} }
catch (Exception e) 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 mod = FieldLoader.Load<ExternalMod>(yaml);
var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon"); var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon");
@@ -74,7 +74,10 @@ namespace OpenRA
mod.Icon = sheetBuilder.Add(bitmap); 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) internal void Register(Manifest mod, string launchPath)
@@ -113,41 +116,57 @@ namespace OpenRA
} }
catch (Exception e) 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()); Log.Write("debug", e.ToString());
} }
}
// Clean up stale mod registrations: /// <summary>
// - LaunchPath no longer exists (uninstalled) /// Removes invalid mod registrations:
// - LaunchPath and mod match the current mod, but version differs (newer version installed on top) /// * LaunchPath no longer exists
List<string> toRemove = null; /// * LaunchPath and mod id matches the active mod, but the version is different
foreach (var kv in mods) /// * 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"))
{ {
var k = kv.Key; string modKey = null;
var m = kv.Value; try
if (!File.Exists(m.LaunchPath) || (m.LaunchPath == launchPath && m.Id == mod.Id && k != key))
{ {
Log.Write("debug", "Removing stale mod metadata entry '{0}'", k); var yaml = MiniYaml.FromStream(File.OpenRead(path), path).First().Value;
if (toRemove == null) var m = FieldLoader.Load<ExternalMod>(yaml);
toRemove = new List<string>(); modKey = ExternalMod.MakeKey(m);
toRemove.Add(k); // Continue to the next entry if this one is valid
var path = Path.Combine(supportPath, k + ".yaml"); if (File.Exists(m.LaunchPath) && Path.GetFileNameWithoutExtension(path) == modKey &&
try !(activeMod != null && m.LaunchPath == activeMod.LaunchPath && m.Id == activeMod.Id && m.Version != activeMod.Version))
{ continue;
File.Delete(path); }
} catch (Exception e)
catch (Exception e) {
{ Log.Write("debug", "Failed to parse mod metadata file '{0}'", path);
Log.Write("debug", "Failed to remove mod metadata file '{0}'", path); Log.Write("debug", e.ToString());
Log.Write("debug", e.ToString()); }
}
// Remove from the ingame mod switcher
if (Path.GetFileNameWithoutExtension(path) == modKey)
mods.Remove(modKey);
// Remove stale or corrupted metadata
try
{
File.Delete(path);
Log.Write("debug", "Removed invalid mod metadata file '{0}'", path);
}
catch (Exception e)
{
Log.Write("debug", "Failed to remove mod metadata file '{0}'", path);
Log.Write("debug", e.ToString());
} }
} }
if (toRemove != null)
foreach (var r in toRemove)
mods.Remove(r);
} }
public ExternalMod this[string key] { get { return mods[key]; } } public ExternalMod this[string key] { get { return mods[key]; } }

View File

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