Rework mod searching/enumeration.

This commit is contained in:
Paul Chote
2017-01-27 17:51:03 +00:00
parent 9b6afd3c37
commit 7d758202c5
4 changed files with 38 additions and 35 deletions

View File

@@ -249,10 +249,10 @@ namespace OpenRA
// Special case handling of Game.Mod argument: if it matches a real filesystem path // Special case handling of Game.Mod argument: if it matches a real filesystem path
// then we use this to override the mod search path, and replace it with the mod id // then we use this to override the mod search path, and replace it with the mod id
var modArgument = args.GetValue("Game.Mod", null); var modArgument = args.GetValue("Game.Mod", null);
string customModPath = null; var explicitModPaths = new string[0];
if (modArgument != null && (File.Exists(modArgument) || Directory.Exists(modArgument))) if (modArgument != null && (File.Exists(modArgument) || Directory.Exists(modArgument)))
{ {
customModPath = modArgument; explicitModPaths = new[] { modArgument };
args.ReplaceValue("Game.Mod", Path.GetFileNameWithoutExtension(modArgument)); args.ReplaceValue("Game.Mod", Path.GetFileNameWithoutExtension(modArgument));
} }
@@ -314,7 +314,8 @@ namespace OpenRA
GlobalChat = new GlobalChat(); GlobalChat = new GlobalChat();
Mods = new InstalledMods(customModPath); var modSearchPaths = new[] { Path.Combine(".", "mods"), Path.Combine("^", "mods") };
Mods = new InstalledMods(modSearchPaths, explicitModPaths);
Console.WriteLine("Internal mods:"); Console.WriteLine("Internal mods:");
foreach (var mod in Mods) foreach (var mod in Mods)
Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version); Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version);

View File

@@ -29,34 +29,35 @@ namespace OpenRA
readonly Dictionary<string, Sprite> icons = new Dictionary<string, Sprite>(); readonly Dictionary<string, Sprite> icons = new Dictionary<string, Sprite>();
public readonly IReadOnlyDictionary<string, Sprite> Icons; public readonly IReadOnlyDictionary<string, Sprite> Icons;
public InstalledMods(string customModPath) /// <summary>Initializes the collection of locally installed mods.</summary>
/// <param name="searchPaths">Filesystem paths to search for mod packages.</param>
/// <param name="explicitPaths">Filesystem paths to additional mod packages.</param>
public InstalledMods(IEnumerable<string> searchPaths, IEnumerable<string> explicitPaths)
{ {
sheetBuilder = new SheetBuilder(SheetType.BGRA, 256); sheetBuilder = new SheetBuilder(SheetType.BGRA, 256);
Icons = new ReadOnlyDictionary<string, Sprite>(icons); Icons = new ReadOnlyDictionary<string, Sprite>(icons);
mods = GetInstalledMods(customModPath); mods = GetInstalledMods(searchPaths, explicitPaths);
} }
static IEnumerable<Pair<string, string>> GetCandidateMods() static IEnumerable<Pair<string, string>> GetCandidateMods(IEnumerable<string> searchPaths)
{ {
// Get mods that are in the game folder. var mods = new List<Pair<string, string>>();
var basePath = Platform.ResolvePath(Path.Combine(".", "mods")); foreach (var path in searchPaths)
var mods = Directory.GetDirectories(basePath) {
.Select(x => Pair.New(x.Substring(basePath.Length + 1), x)) try
.ToList(); {
var directory = new DirectoryInfo(Platform.ResolvePath(path));
foreach (var subdir in directory.EnumerateDirectories())
mods.Add(Pair.New(subdir.Name, subdir.FullName));
foreach (var m in Directory.GetFiles(basePath, "*.oramod")) foreach (var file in directory.EnumerateFiles("*.oramod"))
mods.Add(Pair.New(Path.GetFileNameWithoutExtension(m), m)); mods.Add(Pair.New(Path.GetFileNameWithoutExtension(file.Name), file.FullName));
}
// Get mods that are in the support folder. catch (Exception e)
var supportPath = Platform.ResolvePath(Path.Combine("^", "mods")); {
if (!Directory.Exists(supportPath)) Console.WriteLine("Failed to enumerate mod search path {0}: {1}", path, e.Message);
return mods; }
}
foreach (var pair in Directory.GetDirectories(supportPath).ToDictionary(x => x.Substring(supportPath.Length + 1)))
mods.Add(Pair.New(pair.Key, pair.Value));
foreach (var m in Directory.GetFiles(supportPath, "*.oramod"))
mods.Add(Pair.New(Path.GetFileNameWithoutExtension(m), m));
return mods; return mods;
} }
@@ -102,12 +103,11 @@ namespace OpenRA
} }
} }
Dictionary<string, Manifest> GetInstalledMods(string customModPath) Dictionary<string, Manifest> GetInstalledMods(IEnumerable<string> searchPaths, IEnumerable<string> explicitPaths)
{ {
var ret = new Dictionary<string, Manifest>(); var ret = new Dictionary<string, Manifest>();
var candidates = GetCandidateMods(); var candidates = GetCandidateMods(searchPaths)
if (customModPath != null) .Concat(explicitPaths.Select(p => Pair.New(Path.GetFileNameWithoutExtension(p), p)));
candidates = candidates.Append(Pair.New(Path.GetFileNameWithoutExtension(customModPath), customModPath));
foreach (var pair in candidates) foreach (var pair in candidates)
{ {

View File

@@ -30,10 +30,10 @@ namespace OpenRA.Server
// Special case handling of Game.Mod argument: if it matches a real filesystem path // Special case handling of Game.Mod argument: if it matches a real filesystem path
// then we use this to override the mod search path, and replace it with the mod id // then we use this to override the mod search path, and replace it with the mod id
var modArgument = arguments.GetValue("Game.Mod", null); var modArgument = arguments.GetValue("Game.Mod", null);
string customModPath = null; var explicitModPaths = new string[0];
if (modArgument != null && (File.Exists(modArgument) || Directory.Exists(modArgument))) if (modArgument != null && (File.Exists(modArgument) || Directory.Exists(modArgument)))
{ {
customModPath = modArgument; explicitModPaths = new[] { modArgument };
arguments.ReplaceValue("Game.Mod", Path.GetFileNameWithoutExtension(modArgument)); arguments.ReplaceValue("Game.Mod", Path.GetFileNameWithoutExtension(modArgument));
} }
@@ -43,7 +43,8 @@ namespace OpenRA.Server
var settings = Game.Settings.Server; var settings = Game.Settings.Server;
var mod = Game.Settings.Game.Mod; var mod = Game.Settings.Game.Mod;
var mods = new InstalledMods(customModPath); var modSearchPaths = new[] { Path.Combine(".", "mods"), Path.Combine("^", "mods") };
var mods = new InstalledMods(modSearchPaths, explicitModPaths);
// HACK: The engine code *still* assumes that Game.ModData is set // HACK: The engine code *still* assumes that Game.ModData is set
var modData = Game.ModData = new ModData(mods[mod], mods); var modData = Game.ModData = new ModData(mods[mod], mods);

View File

@@ -47,19 +47,20 @@ namespace OpenRA
if (args.Length == 0) if (args.Length == 0)
{ {
PrintUsage(new InstalledMods(null), null); PrintUsage(new InstalledMods(new string[0], new string[0]), null);
return; return;
} }
var modId = args[0]; var modId = args[0];
string customModPath = null; var explicitModPaths = new string[0];
if (File.Exists(modId) || Directory.Exists(modId)) if (File.Exists(modId) || Directory.Exists(modId))
{ {
customModPath = modId; explicitModPaths = new[] { modId };
modId = Path.GetFileNameWithoutExtension(modId); modId = Path.GetFileNameWithoutExtension(modId);
} }
var mods = new InstalledMods(customModPath); var modSearchPaths = new[] { Path.Combine(".", "mods"), Path.Combine("^", "mods") };
var mods = new InstalledMods(modSearchPaths, explicitModPaths);
if (!mods.Keys.Contains(modId)) if (!mods.Keys.Contains(modId))
{ {
PrintUsage(mods, null); PrintUsage(mods, null);