diff --git a/OpenRA.Game/ExternalMods.cs b/OpenRA.Game/ExternalMods.cs index b95df2b5ff..fa18f61016 100644 --- a/OpenRA.Game/ExternalMods.cs +++ b/OpenRA.Game/ExternalMods.cs @@ -111,6 +111,38 @@ namespace OpenRA Directory.CreateDirectory(supportPath); File.WriteAllLines(Path.Combine(supportPath, key + ".yaml"), yaml.ToLines(false).ToArray()); + + // 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 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(); + + toRemove.Add(k); + var path = Path.Combine(supportPath, k + ".yaml"); + try + { + File.Delete(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]; } } diff --git a/OpenRA.Game/Network/GameServer.cs b/OpenRA.Game/Network/GameServer.cs index 0ef4ac4c3a..f8e3e64024 100644 --- a/OpenRA.Game/Network/GameServer.cs +++ b/OpenRA.Game/Network/GameServer.cs @@ -48,19 +48,19 @@ namespace OpenRA.Network ModId = modVersion[0]; ModVersion = modVersion[1]; - if (Game.Mods.TryGetValue(modVersion[0], out mod)) - { - ModLabel = "{0} ({1})".F(mod.Metadata.Title, modVersion[1]); - IsCompatible = Game.Settings.Debug.IgnoreVersionMismatch || ModVersion == mod.Metadata.Version; - } - var externalKey = ExternalMod.MakeKey(modVersion[0], modVersion[1]); - if (!IsCompatible && Game.ExternalMods.TryGetValue(externalKey, out external) + if (Game.ExternalMods.TryGetValue(externalKey, out external) && external.Version == modVersion[1]) { ModLabel = "{0} ({1})".F(external.Title, external.Version); IsCompatible = true; } + else if (Game.Mods.TryGetValue(modVersion[0], out mod)) + { + // Use internal mod data to populate the section header, but + // on-connect switching must use the external mod plumbing. + ModLabel = "{0} ({1})".F(mod.Metadata.Title, modVersion[1]); + } } var mapAvailable = Game.Settings.Game.AllowDownloading || Game.ModData.MapCache[Map].Status == MapStatus.Available;