Add RequiresMods tag to the mod Manifest

List required mods and their versions to enable mod dependencies on another mods.
Also used for identifying the engine version by `modchooser`'s version.
This commit is contained in:
Pavel Penev
2015-09-09 17:13:13 +03:00
parent ef1e217a2a
commit 9748b556dc
8 changed files with 59 additions and 5 deletions

View File

@@ -253,6 +253,13 @@ namespace OpenRA
RunAfterDelay(Settings.Server.NatDiscoveryTimeout, UPnP.StoppingNatDiscovery);
}
public static bool IsModInstalled(string modId)
{
return Manifest.AllMods[modId].RequiresMods.All(mod => ModMetadata.AllMods.ContainsKey(mod.Key)
&& ModMetadata.AllMods[mod.Key].Version == mod.Value
&& IsModInstalled(mod.Key));
}
public static void InitializeMod(string mod, Arguments args)
{
// Clear static state if we have switched mods
@@ -276,8 +283,8 @@ namespace OpenRA
ModData.Dispose();
ModData = null;
// Fall back to default if the mod doesn't exist
if (!ModMetadata.AllMods.ContainsKey(mod))
// Fall back to default if the mod doesn't exist or has missing prerequisites.
if (!ModMetadata.AllMods.ContainsKey(mod) || !IsModInstalled(mod))
mod = new GameSettings().Mod;
Console.WriteLine("Loading mod: {0}", mod);

View File

@@ -32,6 +32,8 @@ namespace OpenRA
// Describes what is to be loaded in order to run a mod
public class Manifest
{
public static readonly Dictionary<string, Manifest> AllMods = LoadMods();
public readonly ModMetadata Mod;
public readonly string[]
Folders, Rules, ServerTraits,
@@ -44,6 +46,7 @@ namespace OpenRA
public readonly MiniYaml LoadScreen;
public readonly MiniYaml LobbyDefaults;
public readonly Dictionary<string, string> RequiresMods;
public readonly Dictionary<string, Pair<string, int>> Fonts;
public readonly string[] SpriteFormats = { };
@@ -51,7 +54,7 @@ namespace OpenRA
readonly string[] reservedModuleNames = { "Metadata", "Folders", "MapFolders", "Packages", "Rules",
"Sequences", "VoxelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons",
"Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions",
"ServerTraits", "LoadScreen", "LobbyDefaults", "Fonts", "SupportsMapsFrom", "SpriteFormats" };
"ServerTraits", "LoadScreen", "LobbyDefaults", "Fonts", "SupportsMapsFrom", "SpriteFormats", "RequiresMods" };
readonly TypeDictionary modules = new TypeDictionary();
readonly Dictionary<string, MiniYaml> yaml;
@@ -98,6 +101,8 @@ namespace OpenRA
return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value));
});
RequiresMods = yaml["RequiresMods"].ToDictionary(my => my.Value);
// Allow inherited mods to import parent maps.
var compat = new List<string>();
compat.Add(mod);
@@ -174,5 +179,29 @@ namespace OpenRA
return module;
}
static Dictionary<string, Manifest> LoadMods()
{
var basePath = Platform.ResolvePath(".", "mods");
var mods = Directory.GetDirectories(basePath)
.Select(x => x.Substring(basePath.Length + 1));
var ret = new Dictionary<string, Manifest>();
foreach (var mod in mods)
{
try
{
var manifest = new Manifest(mod);
ret.Add(mod, manifest);
}
catch (Exception ex)
{
Log.Write("debug", "An exception occured while trying to load mod {0}:", mod);
Log.Write("debug", ex.ToString());
}
}
return ret;
}
}
}