diff --git a/OpenRA.Game/Map/MapCache.cs b/OpenRA.Game/Map/MapCache.cs index e1765077fe..f85b17fd90 100644 --- a/OpenRA.Game/Map/MapCache.cs +++ b/OpenRA.Game/Map/MapCache.cs @@ -117,7 +117,7 @@ namespace OpenRA } } - public IEnumerable EnumerateMapPackagesWithoutCaching(MapClassification classification = MapClassification.System) + public IEnumerable EnumerateMapDirPackages(MapClassification classification = MapClassification.System) { // Utility mod that does not support maps if (!modData.Manifest.Contains()) @@ -143,16 +143,29 @@ namespace OpenRA continue; using (var package = (IReadWritePackage)modData.ModFiles.OpenPackage(name)) - { - foreach (var map in package.Contents) - { - if (package.OpenPackage(map, modData.ModFiles) is IReadWritePackage mapPackage) - yield return mapPackage; - } - } + yield return package; } } + public IEnumerable<(IReadWritePackage package, string map)> EnumerateMapDirPackagesAndNames(MapClassification classification = MapClassification.System) + { + var mapDirPackages = EnumerateMapDirPackages(classification); + + foreach (var mapDirPackage in mapDirPackages) + foreach (var map in mapDirPackage.Contents) + yield return (mapDirPackage, map); + } + + public IEnumerable EnumerateMapPackagesWithoutCaching(MapClassification classification = MapClassification.System) + { + var mapDirPackages = EnumerateMapDirPackages(classification); + + foreach (var mapDirPackage in mapDirPackages) + foreach (var map in mapDirPackage.Contents) + if (mapDirPackage.OpenPackage(map, modData.ModFiles) is IReadWritePackage mapPackage) + yield return mapPackage; + } + public IEnumerable EnumerateMapsWithoutCaching(MapClassification classification = MapClassification.System) { foreach (var mapPackage in EnumerateMapPackagesWithoutCaching(classification)) diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs index ffd81bfa84..099135a0a5 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CheckYaml.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.UtilityCommands ObjectCreator.MissingTypeAction = s => EmitError($"Missing Type: {s}"); FieldLoader.UnknownFieldAction = (s, f) => EmitError($"FieldLoader: Missing field `{s}` on `{f.Name}`"); - var maps = new List(); + var maps = new List<(IReadWritePackage package, string map)>(); if (args.Length < 2) { Console.WriteLine($"Testing mod: {modData.Manifest.Metadata.Title}"); @@ -78,40 +78,15 @@ namespace OpenRA.Mods.Common.UtilityCommands } // Use all system maps for lint checking - maps = modData.MapCache.EnumerateMapsWithoutCaching().ToList(); + maps = modData.MapCache.EnumerateMapDirPackagesAndNames().ToList(); } else - maps.Add(new Map(modData, new Folder(Platform.EngineDir).OpenPackage(args[1], modData.ModFiles))); + maps.Add((new Folder(Platform.EngineDir), args[1])); - foreach (var testMap in maps) + foreach (var map in maps) { - Console.WriteLine($"Testing map: {testMap.Title}"); - - // Lint tests can't be trusted if the map rules are bogus - // so report that problem then skip the tests - if (testMap.InvalidCustomRules) - { - EmitError(testMap.InvalidCustomRulesException.ToString()); - continue; - } - - // Run all rule checks on the map if it defines custom rules. - if (testMap.RuleDefinitions != null || testMap.VoiceDefinitions != null || testMap.WeaponDefinitions != null) - CheckRules(modData, testMap.Rules, testMap); - - // Run all map-level checks here. - foreach (var customMapPassType in modData.ObjectCreator.GetTypesImplementing()) - { - try - { - var customMapPass = (ILintMapPass)modData.ObjectCreator.CreateBasic(customMapPassType); - customMapPass.Run(EmitError, EmitWarning, modData, testMap); - } - catch (Exception e) - { - EmitError($"{customMapPassType} failed with exception: {e}"); - } - } + var testMap = new Map(modData, map.package.OpenPackage(map.map, modData.ModFiles)); + TestMap(testMap, modData); } if (errors > 0) @@ -127,6 +102,37 @@ namespace OpenRA.Mods.Common.UtilityCommands } } + void TestMap(Map map, ModData modData) + { + Console.WriteLine($"Testing map: {map.Title}"); + + // Lint tests can't be trusted if the map rules are bogus + // so report that problem then skip the tests + if (map.InvalidCustomRules) + { + EmitError(map.InvalidCustomRulesException.ToString()); + return; + } + + // Run all rule checks on the map if it defines custom rules. + if (map.RuleDefinitions != null || map.VoiceDefinitions != null || map.WeaponDefinitions != null) + CheckRules(modData, map.Rules, map); + + // Run all map-level checks here. + foreach (var customMapPassType in modData.ObjectCreator.GetTypesImplementing()) + { + try + { + var customMapPass = (ILintMapPass)modData.ObjectCreator.CreateBasic(customMapPassType); + customMapPass.Run(EmitError, EmitWarning, modData, map); + } + catch (Exception e) + { + EmitError($"{customMapPassType} failed with exception: {e}"); + } + } + } + void CheckRules(ModData modData, Ruleset rules, Map map = null) { foreach (var customRulesPassType in modData.ObjectCreator.GetTypesImplementing())