From 31710c1644a1c09cce87096437c869a084d9b5b7 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 7 Mar 2015 09:29:08 +0000 Subject: [PATCH 1/4] Remove obsolete Movies entry from cnc manifest. --- mods/cnc/mod.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 73ed0758d4..0cfff7afb0 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -121,10 +121,6 @@ ChromeLayout: ./mods/cnc/chrome/assetbrowser.yaml ./mods/cnc/chrome/missionbrowser.yaml -Movies: - ./mods/cnc/movies-gdi.yaml - ./mods/cnc/movies-nod.yaml - Voices: ./mods/cnc/audio/voices.yaml From 5552000d69ca0cb8ba21386e82a5c50f2c8e21d9 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 7 Mar 2015 09:29:50 +0000 Subject: [PATCH 2/4] Allow mods to define custom manifest metadata. --- OpenRA.Game/Manifest.cs | 43 ++++++++++++++++++++++++++++++++++++++++- OpenRA.Game/ModData.cs | 2 ++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/OpenRA.Game/Manifest.cs b/OpenRA.Game/Manifest.cs index deaca44e89..094e92265f 100644 --- a/OpenRA.Game/Manifest.cs +++ b/OpenRA.Game/Manifest.cs @@ -18,6 +18,7 @@ using OpenRA.Primitives; namespace OpenRA { public enum TileShape { Rectangle, Diamond } + public interface IGlobalModData { } // Describes what is to be loaded in order to run a mod public class Manifest @@ -54,10 +55,19 @@ namespace OpenRA [Desc("Default subcell index used if SubCellInit is absent", "0 - full cell, 1 - first sub-cell")] public readonly int SubCellDefaultIndex = 3; + 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", "ContentInstaller", "Fonts", "TileSize", + "TileShape", "SubCells", "SupportsMapsFrom", "SpriteFormats" }; + + readonly TypeDictionary modules = new TypeDictionary(); + readonly Dictionary yaml; + public Manifest(string mod) { var path = Platform.ResolvePath(".", "mods", mod, "mod.yaml"); - var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary(); + yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary(); Mod = FieldLoader.Load(yaml["Metadata"]); Mod.Id = mod; @@ -133,6 +143,23 @@ namespace OpenRA SpriteFormats = FieldLoader.GetValue("SpriteFormats", yaml["SpriteFormats"].Value); } + public void LoadCustomData(ObjectCreator oc) + { + foreach (var kv in yaml) + { + if (reservedModuleNames.Contains(kv.Key)) + continue; + + var t = oc.FindType(kv.Key); + if (t == null || !typeof(IGlobalModData).IsAssignableFrom(t)) + throw new InvalidDataException("`{0}` is not a valid mod manifest entry.".F(kv.Key)); + + var module = oc.CreateObject(kv.Key); + FieldLoader.Load(module, kv.Value); + modules.Add(module); + } + } + static string[] YamlList(Dictionary yaml, string key, bool parsePaths = false) { if (!yaml.ContainsKey(key)) @@ -152,5 +179,19 @@ namespace OpenRA return new ReadOnlyDictionary(inner); } + + public T Get() where T : IGlobalModData + { + var module = modules.GetOrDefault(); + + // Lazily create the default values if not explicitly defined. + if (module == null) + { + module = (T)Game.ModData.ObjectCreator.CreateBasic(typeof(T)); + modules.Add(module); + } + + return module; + } } } diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index 5c9e8d33c7..8cba16ed01 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -38,6 +38,8 @@ namespace OpenRA Languages = new string[0]; Manifest = new Manifest(mod); ObjectCreator = new ObjectCreator(Manifest); + Manifest.LoadCustomData(ObjectCreator); + if (useLoadScreen) { LoadScreen = ObjectCreator.CreateObject(Manifest.LoadScreen.Value); From 2de91a4c4e2841f444fcba56b90b9b0a699dbfa5 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 7 Mar 2015 09:40:01 +0000 Subject: [PATCH 3/4] Convert ContentInstaller into a manifest module. --- OpenRA.Game/InstallUtils.cs | 2 +- OpenRA.Game/Manifest.cs | 6 +----- OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs | 2 +- .../Widgets/Logic/Installation/InstallFromCDLogic.cs | 10 ++++++---- .../Widgets/Logic/Installation/InstallLogic.cs | 4 ++-- .../Widgets/Logic/Installation/InstallMusicLogic.cs | 6 +++--- OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs | 2 +- 7 files changed, 15 insertions(+), 17 deletions(-) diff --git a/OpenRA.Game/InstallUtils.cs b/OpenRA.Game/InstallUtils.cs index f33f447896..f59a2b0eaf 100644 --- a/OpenRA.Game/InstallUtils.cs +++ b/OpenRA.Game/InstallUtils.cs @@ -18,7 +18,7 @@ using OpenRA.FileSystem; namespace OpenRA { - public class InstallData + public class ContentInstaller : IGlobalModData { public readonly string MenuWidget = null; public readonly string MusicMenuWidget = null; diff --git a/OpenRA.Game/Manifest.cs b/OpenRA.Game/Manifest.cs index 094e92265f..b01f8f7f14 100644 --- a/OpenRA.Game/Manifest.cs +++ b/OpenRA.Game/Manifest.cs @@ -34,7 +34,6 @@ namespace OpenRA public readonly IReadOnlyDictionary MapFolders; public readonly MiniYaml LoadScreen; public readonly MiniYaml LobbyDefaults; - public readonly InstallData ContentInstaller; public readonly Dictionary> Fonts; public readonly Size TileSize = new Size(24, 24); public readonly TileShape TileShape = TileShape.Rectangle; @@ -58,7 +57,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", "ContentInstaller", "Fonts", "TileSize", + "ServerTraits", "LoadScreen", "LobbyDefaults", "Fonts", "TileSize", "TileShape", "SubCells", "SupportsMapsFrom", "SpriteFormats" }; readonly TypeDictionary modules = new TypeDictionary(); @@ -96,9 +95,6 @@ namespace OpenRA LoadScreen = yaml["LoadScreen"]; LobbyDefaults = yaml["LobbyDefaults"]; - if (yaml.ContainsKey("ContentInstaller")) - ContentInstaller = FieldLoader.Load(yaml["ContentInstaller"]); - Fonts = yaml["Fonts"].ToDictionary(my => { var nd = my.ToDictionary(); diff --git a/OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs b/OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs index 6a4bfe5ed0..37722cd67a 100644 --- a/OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs +++ b/OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.LoadScreens // Check whether the mod content is installed // TODO: The installation code has finally been beaten into shape, so we can // finally move it all into the planned "Manage Content" panel in the modchooser mod. - var installData = Game.ModData.Manifest.ContentInstaller; + var installData = Game.ModData.Manifest.Get(); var installModContent = !installData.TestFiles.All(f => GlobalFileSystem.Exists(f)); var installModMusic = args != null && args.Contains("Install.Music"); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs index 4e81894ae0..0f2524265f 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs @@ -24,10 +24,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly Action continueLoading; readonly ButtonWidget retryButton, backButton; readonly Widget installingContainer, insertDiskContainer; + readonly ContentInstaller installData; [ObjectCreator.UseCtor] public InstallFromCDLogic(Widget widget, Action continueLoading) { + installData = Game.ModData.Manifest.Get(); this.continueLoading = continueLoading; panel = widget.Get("INSTALL_FROMCD_PANEL"); progressBar = panel.Get("PROGRESS_BAR"); @@ -46,7 +48,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic bool IsValidDisk(string diskRoot) { - return Game.ModData.Manifest.ContentInstaller.DiskTestFiles.All(f => File.Exists(Path.Combine(diskRoot, f))); + return installData.DiskTestFiles.All(f => File.Exists(Path.Combine(diskRoot, f))); } void CheckForDisk() @@ -70,13 +72,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic installingContainer.IsVisible = () => true; var dest = Platform.ResolvePath("^", "Content", Game.ModData.Manifest.Mod.Id); - var copyFiles = Game.ModData.Manifest.ContentInstaller.CopyFilesFromCD; + var copyFiles = installData.CopyFilesFromCD; - var packageToExtract = Game.ModData.Manifest.ContentInstaller.PackageToExtractFromCD.Split(':'); + var packageToExtract = installData.PackageToExtractFromCD.Split(':'); var extractPackage = packageToExtract.First(); var annotation = packageToExtract.Length > 1 ? packageToExtract.Last() : null; - var extractFiles = Game.ModData.Manifest.ContentInstaller.ExtractFilesFromCD; + var extractFiles = installData.ExtractFilesFromCD; var installCounter = 0; var installTotal = copyFiles.Length + extractFiles.Length; diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallLogic.cs index e35bc9bea6..dff55c86e6 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallLogic.cs @@ -19,13 +19,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic [ObjectCreator.UseCtor] public InstallLogic(Widget widget, Action continueLoading) { - var mirrorListUrl = Game.ModData.Manifest.ContentInstaller.PackageMirrorList; + var installData = Game.ModData.Manifest.Get(); var panel = widget.Get("INSTALL_PANEL"); var widgetArgs = new WidgetArgs() { { "afterInstall", () => { Ui.CloseWindow(); continueLoading(); } }, { "continueLoading", continueLoading }, - { "mirrorListUrl", mirrorListUrl }, + { "mirrorListUrl", installData.PackageMirrorList }, }; panel.Get("DOWNLOAD_BUTTON").OnClick = () => diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallMusicLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallMusicLogic.cs index be0134846f..b3c7017a6a 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallMusicLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallMusicLogic.cs @@ -42,13 +42,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic var downloadButton = installMusicContainer.GetOrNull("DOWNLOAD_BUTTON"); if (downloadButton != null) { - var mirrorListUrl = Game.ModData.Manifest.ContentInstaller.MusicPackageMirrorList; - downloadButton.IsVisible = () => !string.IsNullOrEmpty(mirrorListUrl); + var installData = Game.ModData.Manifest.Get(); + downloadButton.IsVisible = () => !string.IsNullOrEmpty(installData.MusicPackageMirrorList); downloadButton.OnClick = () => { Ui.OpenWindow("INSTALL_DOWNLOAD_PANEL", new WidgetArgs() { { "afterInstall", () => Game.InitializeMod(Game.Settings.Game.Mod, null) }, - { "mirrorListUrl", mirrorListUrl }, + { "mirrorListUrl", installData.MusicPackageMirrorList }, }); }; } diff --git a/OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs index e109d97a77..d8f9c41c75 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs @@ -92,7 +92,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic Game.InitializeMod(Game.Settings.Game.Mod, new Arguments(args)); }; - var installData = Game.ModData.Manifest.ContentInstaller; + var installData = Game.ModData.Manifest.Get(); installButton.IsVisible = () => modRules.InstalledMusic.ToArray().Length <= installData.ShippedSoundtracks; } From dcfc62f33383982e621f317ea4e0b67d0991dffc Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 7 Mar 2015 09:42:08 +0000 Subject: [PATCH 4/4] Move InstallUtils from Game to Mods.Common. --- OpenRA.Game/OpenRA.Game.csproj | 1 - {OpenRA.Game => OpenRA.Mods.Common}/InstallUtils.cs | 2 +- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 5 +++++ 3 files changed, 6 insertions(+), 2 deletions(-) rename {OpenRA.Game => OpenRA.Mods.Common}/InstallUtils.cs (99%) diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index af61ef4bf9..ae14e7c544 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -275,7 +275,6 @@ - diff --git a/OpenRA.Game/InstallUtils.cs b/OpenRA.Mods.Common/InstallUtils.cs similarity index 99% rename from OpenRA.Game/InstallUtils.cs rename to OpenRA.Mods.Common/InstallUtils.cs index f59a2b0eaf..c545b56f20 100644 --- a/OpenRA.Game/InstallUtils.cs +++ b/OpenRA.Mods.Common/InstallUtils.cs @@ -16,7 +16,7 @@ using ICSharpCode.SharpZipLib; using ICSharpCode.SharpZipLib.Zip; using OpenRA.FileSystem; -namespace OpenRA +namespace OpenRA.Mods.Common { public class ContentInstaller : IGlobalModData { diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 6747ef62d6..4010600547 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -63,6 +63,10 @@ ..\thirdparty\Mono.Nat.dll False + + ..\thirdparty\ICSharpCode.SharpZipLib.dll + False + @@ -572,6 +576,7 @@ +