Merge pull request #11771 from pchote/split-content-files
Rework mod enumeration and split content metadata into their own files.
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.Common.Widgets.Logic;
|
||||
using OpenRA.Widgets;
|
||||
@@ -21,8 +22,12 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
public class BlankLoadScreen : ILoadScreen
|
||||
{
|
||||
public LaunchArguments Launch;
|
||||
ModData modData;
|
||||
|
||||
public virtual void Init(ModData m, Dictionary<string, string> info) { }
|
||||
public virtual void Init(ModData modData, Dictionary<string, string> info)
|
||||
{
|
||||
this.modData = modData;
|
||||
}
|
||||
|
||||
public virtual void Display()
|
||||
{
|
||||
@@ -79,7 +84,7 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
if (replayMeta != null)
|
||||
{
|
||||
var mod = replayMeta.GameInfo.Mod;
|
||||
if (mod != null && mod != Game.ModData.Manifest.Mod.Id && ModMetadata.AllMods.ContainsKey(mod))
|
||||
if (mod != null && mod != Game.ModData.Manifest.Id && Game.Mods.ContainsKey(mod))
|
||||
Game.InitializeMod(mod, args);
|
||||
}
|
||||
|
||||
@@ -97,5 +102,13 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public bool RequiredContentIsInstalled()
|
||||
{
|
||||
var content = modData.Manifest.Get<ModContent>();
|
||||
return content.Packages
|
||||
.Where(p => p.Value.Required)
|
||||
.All(p => p.Value.TestFiles.All(f => File.Exists(Platform.ResolvePath(f))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,8 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
|
||||
public override void Init(ModData modData, Dictionary<string, string> info)
|
||||
{
|
||||
base.Init(modData, info);
|
||||
|
||||
// Avoid standard loading mechanisms so we
|
||||
// can display the loadscreen as early as possible
|
||||
r = Game.Renderer;
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
@@ -58,5 +57,10 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
if (sprite != null)
|
||||
sprite.Sheet.Dispose();
|
||||
}
|
||||
|
||||
public bool RequiredContentIsInstalled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
115
OpenRA.Mods.Common/ModContent.cs
Normal file
115
OpenRA.Mods.Common/ModContent.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2016 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class ModContent : IGlobalModData
|
||||
{
|
||||
public enum SourceType { Disc, Install }
|
||||
public class ModPackage
|
||||
{
|
||||
public readonly string Title;
|
||||
public readonly string[] TestFiles = { };
|
||||
public readonly string[] Sources = { };
|
||||
public readonly bool Required;
|
||||
public readonly string Download;
|
||||
|
||||
public ModPackage(MiniYaml yaml)
|
||||
{
|
||||
Title = yaml.Value;
|
||||
FieldLoader.Load(this, yaml);
|
||||
}
|
||||
|
||||
public bool IsInstalled()
|
||||
{
|
||||
return TestFiles.All(file => File.Exists(Path.GetFullPath(Platform.ResolvePath(file))));
|
||||
}
|
||||
}
|
||||
|
||||
public class ModSource
|
||||
{
|
||||
public readonly SourceType Type = SourceType.Disc;
|
||||
|
||||
// Used to find installation locations for SourceType.Install
|
||||
public readonly string RegistryKey;
|
||||
public readonly string RegistryValue;
|
||||
|
||||
public readonly string Title;
|
||||
public readonly Dictionary<string, string> IDFiles;
|
||||
|
||||
[FieldLoader.Ignore] public readonly List<MiniYamlNode> Install;
|
||||
|
||||
public ModSource(MiniYaml yaml)
|
||||
{
|
||||
Title = yaml.Value;
|
||||
var installNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Install");
|
||||
if (installNode != null)
|
||||
Install = installNode.Value.Nodes;
|
||||
|
||||
FieldLoader.Load(this, yaml);
|
||||
}
|
||||
}
|
||||
|
||||
public class ModDownload
|
||||
{
|
||||
public readonly string Title;
|
||||
public readonly string URL;
|
||||
public readonly string MirrorList;
|
||||
public readonly Dictionary<string, string> Extract;
|
||||
|
||||
public ModDownload(MiniYaml yaml)
|
||||
{
|
||||
Title = yaml.Value;
|
||||
FieldLoader.Load(this, yaml);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly string InstallPromptMessage;
|
||||
public readonly string QuickDownload;
|
||||
public readonly string HeaderMessage;
|
||||
|
||||
[FieldLoader.LoadUsing("LoadPackages")]
|
||||
public readonly Dictionary<string, ModPackage> Packages = new Dictionary<string, ModPackage>();
|
||||
|
||||
static object LoadPackages(MiniYaml yaml)
|
||||
{
|
||||
var packages = new Dictionary<string, ModPackage>();
|
||||
var packageNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Packages");
|
||||
if (packageNode != null)
|
||||
foreach (var node in packageNode.Value.Nodes)
|
||||
packages.Add(node.Key, new ModPackage(node.Value));
|
||||
|
||||
return packages;
|
||||
}
|
||||
|
||||
[FieldLoader.LoadUsing("LoadDownloads")]
|
||||
public readonly string[] Downloads = { };
|
||||
|
||||
static object LoadDownloads(MiniYaml yaml)
|
||||
{
|
||||
var downloadNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Downloads");
|
||||
return downloadNode != null ? downloadNode.Value.Nodes.Select(n => n.Key).ToArray() : new string[0];
|
||||
}
|
||||
|
||||
[FieldLoader.LoadUsing("LoadSources")]
|
||||
public readonly string[] Sources = { };
|
||||
|
||||
static object LoadSources(MiniYaml yaml)
|
||||
{
|
||||
var sourceNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Sources");
|
||||
return sourceNode != null ? sourceNode.Value.Nodes.Select(n => n.Key).ToArray() : new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -778,6 +778,7 @@
|
||||
<Compile Include="Activities\Air\FlyCircleTimed.cs" />
|
||||
<Compile Include="UtilityCommands\ListInstallShieldCabContentsCommand.cs" />
|
||||
<Compile Include="FileFormats\InstallShieldCABCompression.cs" />
|
||||
<Compile Include="ModContent.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
lastPing = Game.RunTime;
|
||||
isBusy = true;
|
||||
|
||||
var mod = server.ModData.Manifest.Mod;
|
||||
var mod = server.ModData.Manifest;
|
||||
|
||||
// important to grab these on the main server thread, not in the worker we're about to spawn -- they may be modified
|
||||
// by the main thread as clients join and leave.
|
||||
@@ -79,7 +79,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
(int)server.State,
|
||||
numPlayers,
|
||||
numBots,
|
||||
"{0}@{1}".F(mod.Id, mod.Version),
|
||||
"{0}@{1}".F(mod.Id, mod.Metadata.Version),
|
||||
server.LobbyInfo.GlobalSettings.Map,
|
||||
numSlots,
|
||||
numSpectators,
|
||||
|
||||
@@ -17,22 +17,22 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class CheckCodeStyle : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--check-code-style"; } }
|
||||
string IUtilityCommand.Name { get { return "--check-code-style"; } }
|
||||
int violationCount;
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
|
||||
[Desc("DIRECTORY", "Check the *.cs source code files in a directory for code style violations.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var relativePath = args[1];
|
||||
var projectPath = Path.GetFullPath(relativePath);
|
||||
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
Game.ModData = utility.ModData;
|
||||
|
||||
var console = new StyleCopConsole(null, false, null, null, true);
|
||||
var project = new CodeProject(0, projectPath, new Configuration(null));
|
||||
|
||||
@@ -28,9 +28,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
int violationCount;
|
||||
|
||||
[Desc("Check for explicit interface implementation violations in all assemblies referenced by the specified mod.")]
|
||||
void IUtilityCommand.Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var types = modData.ObjectCreator.GetTypes();
|
||||
var types = utility.ModData.ObjectCreator.GetTypes();
|
||||
|
||||
foreach (var implementingType in types.Where(t => !t.IsInterface))
|
||||
{
|
||||
|
||||
@@ -17,18 +17,18 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class CheckSquenceSprites : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--check-sequence-sprites"; } }
|
||||
string IUtilityCommand.Name { get { return "--check-sequence-sprites"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("Check the sequence definitions for missing sprite files.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
var failed = false;
|
||||
modData.SpriteSequenceLoader.OnMissingSpriteError = s => { Console.WriteLine("\t" + s); failed = true; };
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class CheckYaml : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--check-yaml"; } }
|
||||
string IUtilityCommand.Name { get { return "--check-yaml"; } }
|
||||
|
||||
static int errors = 0;
|
||||
|
||||
@@ -34,16 +34,16 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
Console.WriteLine("OpenRA.Utility(1,1): Warning: {0}", e);
|
||||
}
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("[MAPFILE]", "Check a mod or map for certain yaml errors.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
var maps = new List<Map>();
|
||||
if (args.Length < 2)
|
||||
{
|
||||
Console.WriteLine("Testing mod: {0}".F(modData.Manifest.Mod.Title));
|
||||
Console.WriteLine("Testing mod: {0}".F(modData.Manifest.Metadata.Title));
|
||||
|
||||
// Run all rule checks on the default mod rules.
|
||||
CheckRules(modData, modData.DefaultRules);
|
||||
|
||||
@@ -23,15 +23,15 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ConvertPngToShpCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--shp"; } }
|
||||
string IUtilityCommand.Name { get { return "--shp"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
|
||||
[Desc("PNGFILE [PNGFILE ...]", "Combine a list of PNG images into a SHP")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var inputFiles = GlobArgs(args).OrderBy(a => a).ToList();
|
||||
var dest = inputFiles[0].Split('-').First() + ".shp";
|
||||
|
||||
@@ -21,19 +21,19 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ConvertSpriteToPngCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--png"; } }
|
||||
string IUtilityCommand.Name { get { return "--png"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 3;
|
||||
}
|
||||
|
||||
[Desc("SPRITEFILE PALETTE [--noshadow] [--nopadding]",
|
||||
"Convert a shp/tmp/R8 to a series of PNGs, optionally removing shadow")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
var src = args[1];
|
||||
var shadowIndex = new int[] { };
|
||||
|
||||
@@ -16,15 +16,15 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class CreateManPage : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--man-page"; } }
|
||||
string IUtilityCommand.Name { get { return "--man-page"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("Create a man page in troff format.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
Console.WriteLine(".TH OPENRA 6");
|
||||
Console.WriteLine(".SH NAME");
|
||||
|
||||
@@ -17,21 +17,21 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ExtractFilesCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--extract"; } }
|
||||
string IUtilityCommand.Name { get { return "--extract"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
|
||||
[Desc("Extract files from mod packages to the current directory")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var files = args.Skip(1);
|
||||
|
||||
foreach (var f in files)
|
||||
{
|
||||
var src = modData.DefaultFileSystem.Open(f);
|
||||
var src = utility.ModData.DefaultFileSystem.Open(f);
|
||||
if (src == null)
|
||||
throw new InvalidOperationException("File not found: {0}".F(f));
|
||||
var data = src.ReadAllBytes();
|
||||
|
||||
@@ -18,20 +18,20 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ExtractLanguageStringsCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--extract-language-strings"; } }
|
||||
string IUtilityCommand.Name { get { return "--extract-language-strings"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("Extract translatable strings that are not yet localized and update chrome layout.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
var types = Game.ModData.ObjectCreator.GetTypes();
|
||||
var types = modData.ObjectCreator.GetTypes();
|
||||
var translatableFields = types.SelectMany(t => t.GetFields())
|
||||
.Where(f => f.HasAttribute<TranslateAttribute>()).Distinct();
|
||||
|
||||
|
||||
@@ -18,20 +18,20 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ExtractLuaDocsCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--lua-docs"; } }
|
||||
string IUtilityCommand.Name { get { return "--lua-docs"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("Generate Lua API documentation in MarkDown format.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
Game.ModData = utility.ModData;
|
||||
|
||||
Console.WriteLine("This is an automatically generated listing of the new Lua map scripting API, generated for {0} of OpenRA.", Game.ModData.Manifest.Mod.Version);
|
||||
Console.WriteLine("This is an automatically generated listing of the new Lua map scripting API, generated for {0} of OpenRA.", Game.ModData.Manifest.Metadata.Version);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("OpenRA allows custom maps and missions to be scripted using Lua 5.1.\n" +
|
||||
"These scripts run in a sandbox that prevents access to unsafe functions (e.g. OS or file access), " +
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
Console.WriteLine("For a basic guide about map scripts see the [`Map Scripting` wiki page](https://github.com/OpenRA/OpenRA/wiki/Map-scripting).");
|
||||
Console.WriteLine();
|
||||
|
||||
var tables = Game.ModData.ObjectCreator.GetTypesImplementing<ScriptGlobal>()
|
||||
var tables = utility.ModData.ObjectCreator.GetTypesImplementing<ScriptGlobal>()
|
||||
.OrderBy(t => t.Name);
|
||||
|
||||
Console.WriteLine("<h3>Global Tables</h3>");
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
|
||||
Console.WriteLine("<h3>Actor Properties / Commands</h3>");
|
||||
|
||||
var actorCategories = Game.ModData.ObjectCreator.GetTypesImplementing<ScriptActorProperties>().SelectMany(cg =>
|
||||
var actorCategories = utility.ModData.ObjectCreator.GetTypesImplementing<ScriptActorProperties>().SelectMany(cg =>
|
||||
{
|
||||
var catAttr = cg.GetCustomAttributes<ScriptPropertyGroupAttribute>(false).FirstOrDefault();
|
||||
var category = catAttr != null ? catAttr.Category : "Unsorted";
|
||||
@@ -122,7 +122,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
|
||||
Console.WriteLine("<h3>Player Properties / Commands</h3>");
|
||||
|
||||
var playerCategories = Game.ModData.ObjectCreator.GetTypesImplementing<ScriptPlayerProperties>().SelectMany(cg =>
|
||||
var playerCategories = utility.ModData.ObjectCreator.GetTypesImplementing<ScriptPlayerProperties>().SelectMany(cg =>
|
||||
{
|
||||
var catAttr = cg.GetCustomAttributes<ScriptPropertyGroupAttribute>(false).FirstOrDefault();
|
||||
var category = catAttr != null ? catAttr.Category : "Unsorted";
|
||||
|
||||
@@ -50,9 +50,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
[Desc("MAPFILE", "Merge custom map rules into a form suitable for including in map.yaml.")]
|
||||
void IUtilityCommand.Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
var map = new Map(modData, modData.ModFiles.OpenPackage(args[1], new Folder(".")));
|
||||
MergeAndPrint(map, "Rules", map.RuleDefinitions);
|
||||
|
||||
@@ -16,21 +16,21 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ExtractSettingsDocsCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--settings-docs"; } }
|
||||
string IUtilityCommand.Name { get { return "--settings-docs"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("Generate settings documentation in markdown format.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
Game.ModData = modData;
|
||||
Game.ModData = utility.ModData;
|
||||
Console.WriteLine(
|
||||
"This documentation is aimed at server administrators. It displays all settings with default values and description. " +
|
||||
"Please do not edit it directly, but add new `[Desc(\"String\")]` tags to the source code. This file has been " +
|
||||
"automatically generated for version {0} of OpenRA.", Game.ModData.Manifest.Mod.Version);
|
||||
"automatically generated for version {0} of OpenRA.", utility.ModData.Manifest.Metadata.Version);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("All settings can be changed by starting the game via a command-line parameter like `Game.Mod=ra`.");
|
||||
Console.WriteLine();
|
||||
|
||||
@@ -20,23 +20,23 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ExtractTraitDocsCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--docs"; } }
|
||||
string IUtilityCommand.Name { get { return "--docs"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[Desc("Generate trait documentation in MarkDown format.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
Game.ModData = utility.ModData;
|
||||
|
||||
Console.WriteLine(
|
||||
"This documentation is aimed at modders. It displays all traits with default values and developer commentary. " +
|
||||
"Please do not edit it directly, but add new `[Desc(\"String\")]` tags to the source code. This file has been " +
|
||||
"automatically generated for version {0} of OpenRA.", Game.ModData.Manifest.Mod.Version);
|
||||
"automatically generated for version {0} of OpenRA.", utility.ModData.Manifest.Metadata.Version);
|
||||
Console.WriteLine();
|
||||
|
||||
var toc = new StringBuilder();
|
||||
|
||||
@@ -20,18 +20,18 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class FixClassicTilesets : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--fix-classic-tilesets"; } }
|
||||
string IUtilityCommand.Name { get { return "--fix-classic-tilesets"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
|
||||
[Desc("EXTENSIONS", "Fixes missing template tile definitions and adds filename extensions.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
var imageField = typeof(TerrainTemplateInfo).GetField("Image");
|
||||
var pickAnyField = typeof(TerrainTemplateInfo).GetField("PickAny");
|
||||
|
||||
@@ -16,17 +16,17 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class GetMapHashCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--map-hash"; } }
|
||||
string IUtilityCommand.Name { get { return "--map-hash"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
|
||||
[Desc("MAPFILE", "Generate hash of specified oramap file.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
using (var package = modData.ModFiles.OpenPackage(args[1], new Folder(".")))
|
||||
using (var package = utility.ModData.ModFiles.OpenPackage(args[1], new Folder(".")))
|
||||
Console.WriteLine(Map.ComputeUID(package));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,18 +38,15 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
bool singlePlayer;
|
||||
int spawnCount;
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
protected bool ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
|
||||
[Desc("FILENAME", "Convert a legacy INI/MPR map to the OpenRA format.")]
|
||||
public virtual void Run(ModData modData, string[] args)
|
||||
protected void Run(Utility utility, string[] args)
|
||||
{
|
||||
ModData = modData;
|
||||
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
Game.ModData = ModData = utility.ModData;
|
||||
|
||||
var filename = args[1];
|
||||
using (var stream = File.OpenRead(filename))
|
||||
@@ -68,16 +65,16 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
|
||||
// The original game isn't case sensitive, but we are.
|
||||
var tileset = GetTileset(mapSection).ToUpperInvariant();
|
||||
if (!modData.DefaultTileSets.ContainsKey(tileset))
|
||||
if (!ModData.DefaultTileSets.ContainsKey(tileset))
|
||||
throw new InvalidDataException("Unknown tileset {0}".F(tileset));
|
||||
|
||||
Map = new Map(modData, modData.DefaultTileSets[tileset], MapSize, MapSize)
|
||||
Map = new Map(ModData, ModData.DefaultTileSets[tileset], MapSize, MapSize)
|
||||
{
|
||||
Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)),
|
||||
Author = "Westwood Studios",
|
||||
};
|
||||
|
||||
Map.RequiresMod = modData.Manifest.Mod.Id;
|
||||
Map.RequiresMod = ModData.Manifest.Id;
|
||||
|
||||
SetBounds(Map, mapSection);
|
||||
|
||||
|
||||
@@ -19,15 +19,15 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ListInstallShieldCabContentsCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--list-installshield-cab"; } }
|
||||
string IUtilityCommand.Name { get { return "--list-installshield-cab"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length == 2;
|
||||
}
|
||||
|
||||
[Desc("DATA.HDR", "Lists the filenames contained within an Installshield CAB volume set")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
using (var file = File.OpenRead(args[1]))
|
||||
{
|
||||
|
||||
@@ -11,27 +11,26 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.FileSystem;
|
||||
|
||||
namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ListInstallShieldContents : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--list-installshield"; } }
|
||||
string IUtilityCommand.Name { get { return "--list-installshield"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length == 2;
|
||||
}
|
||||
|
||||
[Desc("ARCHIVE.Z", "Lists the content ranges for a InstallShield V3 file")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var filename = Path.GetFileName(args[1]);
|
||||
var path = Path.GetDirectoryName(args[1]);
|
||||
|
||||
var fs = new OpenRA.FileSystem.FileSystem();
|
||||
var fs = new FileSystem.FileSystem(utility.Mods);
|
||||
fs.Mount(path, "parent");
|
||||
var package = new InstallShieldPackage(fs, "parent|" + filename);
|
||||
|
||||
|
||||
@@ -17,15 +17,15 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ListMSCabContentsCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--list-mscab"; } }
|
||||
string IUtilityCommand.Name { get { return "--list-mscab"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length == 2;
|
||||
}
|
||||
|
||||
[Desc("ARCHIVE.CAB", "Lists the filenames contained within a MSCAB file")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var package = new MSCabCompression(File.OpenRead(args[1]));
|
||||
foreach (var file in package.Contents)
|
||||
|
||||
@@ -18,23 +18,23 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ListMixContents : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--list-mix"; } }
|
||||
string IUtilityCommand.Name { get { return "--list-mix"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length == 2;
|
||||
}
|
||||
|
||||
[Desc("ARCHIVE.MIX", "Lists the content ranges for a mix file")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var filename = Path.GetFileName(args[1]);
|
||||
var path = Path.GetDirectoryName(args[1]);
|
||||
|
||||
var fs = new OpenRA.FileSystem.FileSystem();
|
||||
var fs = new FileSystem.FileSystem(utility.Mods);
|
||||
|
||||
// Needed to access the global mix database
|
||||
fs.LoadFromManifest(modData.Manifest);
|
||||
fs.LoadFromManifest(utility.ModData.Manifest);
|
||||
|
||||
fs.Mount(path, "parent");
|
||||
var package = new MixFile(fs, "parent|" + filename);
|
||||
|
||||
@@ -15,16 +15,17 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
[Desc("ACTOR-TYPE [PATH/TO/MAP]", "Display the finalized, merged MiniYaml tree for the given actor type. Input values are case-sensitive.")]
|
||||
void IUtilityCommand.Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
var actorType = args[1];
|
||||
string mapPath = null;
|
||||
|
||||
Map map = null;
|
||||
if (args.Length == 3)
|
||||
{
|
||||
try
|
||||
{
|
||||
mapPath = args[2];
|
||||
@@ -35,6 +36,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
Console.WriteLine("Could not load map '{0}'.", mapPath);
|
||||
Environment.Exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
var fs = map ?? modData.DefaultFileSystem;
|
||||
var topLevelNodes = MiniYaml.Load(fs, modData.Manifest.Rules, map == null ? null : map.RuleDefinitions);
|
||||
|
||||
@@ -22,15 +22,15 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class RemapShpCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--remap"; } }
|
||||
string IUtilityCommand.Name { get { return "--remap"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 5;
|
||||
}
|
||||
|
||||
[Desc("SRCMOD:PAL DESTMOD:PAL SRCSHP DESTSHP", "Remap SHPs to another palette")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var remap = new Dictionary<int, int>();
|
||||
|
||||
@@ -39,14 +39,14 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
remap[i] = i;
|
||||
|
||||
var srcMod = args[1].Split(':')[0];
|
||||
var srcModData = new ModData(srcMod);
|
||||
var srcModData = new ModData(utility.Mods[srcMod], utility.Mods);
|
||||
Game.ModData = srcModData;
|
||||
|
||||
var srcPaletteInfo = srcModData.DefaultRules.Actors["player"].TraitInfo<PlayerColorPaletteInfo>();
|
||||
var srcRemapIndex = srcPaletteInfo.RemapIndex;
|
||||
|
||||
var destMod = args[2].Split(':')[0];
|
||||
var destModData = new ModData(destMod);
|
||||
var destModData = new ModData(utility.Mods[destMod], utility.Mods);
|
||||
Game.ModData = destModData;
|
||||
var destPaletteInfo = destModData.DefaultRules.Actors["player"].TraitInfo<PlayerColorPaletteInfo>();
|
||||
var destRemapIndex = destPaletteInfo.RemapIndex;
|
||||
|
||||
@@ -17,15 +17,15 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class ReplayMetadataCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--replay-metadata"; } }
|
||||
string IUtilityCommand.Name { get { return "--replay-metadata"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
|
||||
[Desc("REPLAYFILE", "Print the game metadata from a replay file.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
var replay = ReplayMetadata.Read(args[1]);
|
||||
if (replay == null)
|
||||
|
||||
@@ -18,14 +18,14 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
public class ResizeMapCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--resize-map"; } }
|
||||
string IUtilityCommand.Name { get { return "--resize-map"; } }
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
Map map;
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
if (args.Length < 4)
|
||||
return false;
|
||||
@@ -46,9 +46,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
[Desc("MAPFILE", "WIDTH", "HEIGHT", "Resize the map at the bottom corners.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
map = new Map(modData, modData.ModFiles.OpenPackage(args[1], new Folder(".")));
|
||||
Console.WriteLine("Resizing map {0} from {1} to {2},{3}", map.Title, map.MapSize, width, height);
|
||||
map.Resize(width, height);
|
||||
|
||||
@@ -15,11 +15,11 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class Rgba2Hex : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--rgba2hex"; } }
|
||||
string IUtilityCommand.Name { get { return "--rgba2hex"; } }
|
||||
|
||||
static readonly char[] Comma = new char[] { ',' };
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
if (args.Length <= 1)
|
||||
return PrintUsage();
|
||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
[Desc("Convert r,g,b[,a] triples/quads into hex colors")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
for (int i = 1; i < args.Length;)
|
||||
{
|
||||
@@ -104,11 +104,11 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
|
||||
class Argb2Hex : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--argb2hex"; } }
|
||||
string IUtilityCommand.Name { get { return "--argb2hex"; } }
|
||||
|
||||
static readonly char[] Comma = new char[] { ',' };
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
if (args.Length <= 1)
|
||||
return PrintUsage();
|
||||
@@ -180,7 +180,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
[Desc("Convert a,r,g,b legacy colors into hex colors")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
for (int i = 1; i < args.Length;)
|
||||
{
|
||||
|
||||
@@ -19,9 +19,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class UpgradeMapCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--upgrade-map"; } }
|
||||
string IUtilityCommand.Name { get { return "--upgrade-map"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 3;
|
||||
}
|
||||
@@ -75,10 +75,10 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
[Desc("MAP", "CURRENTENGINE", "Upgrade map rules to the latest engine version.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
|
||||
// HACK: We know that maps can only be oramap or folders, which are ReadWrite
|
||||
var package = modData.ModFiles.OpenPackage(args[1], new Folder(".")) as IReadWritePackage;
|
||||
|
||||
@@ -19,9 +19,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
class UpgradeModCommand : IUtilityCommand
|
||||
{
|
||||
public string Name { get { return "--upgrade-mod"; } }
|
||||
string IUtilityCommand.Name { get { return "--upgrade-mod"; } }
|
||||
|
||||
public bool ValidateArguments(string[] args)
|
||||
bool IUtilityCommand.ValidateArguments(string[] args)
|
||||
{
|
||||
return args.Length >= 2;
|
||||
}
|
||||
@@ -53,10 +53,10 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
[Desc("CURRENTENGINE", "Upgrade mod rules to the latest engine version.")]
|
||||
public void Run(ModData modData, string[] args)
|
||||
void IUtilityCommand.Run(Utility utility, string[] args)
|
||||
{
|
||||
// HACK: The engine code assumes that Game.modData is set.
|
||||
Game.ModData = modData;
|
||||
var modData = Game.ModData = utility.ModData;
|
||||
modData.MapCache.LoadMaps();
|
||||
|
||||
var engineDate = Exts.ParseIntegerInvariant(args[1]);
|
||||
|
||||
@@ -346,7 +346,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
if (engineVersion < 20160730 && modData.Manifest.Mod.Id == "d2k" && depth == 2)
|
||||
if (engineVersion < 20160730 && modData.Manifest.Id == "d2k" && depth == 2)
|
||||
{
|
||||
if (node.Key == "Start")
|
||||
node.Value.Value = RemapD2k106Sequence(FieldLoader.GetValue<int>("", node.Value.Value)).ToString();
|
||||
@@ -416,7 +416,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
// Fix RA building footprints to not use _ when it's not necessary
|
||||
if (engineVersion < 20160619 && modData.Manifest.Mod.Id == "ra" && depth == 1)
|
||||
if (engineVersion < 20160619 && modData.Manifest.Id == "ra" && depth == 1)
|
||||
{
|
||||
var buildings = new List<string>() { "tsla", "gap", "agun", "apwr", "fapw" };
|
||||
if (buildings.Contains(parent.Value.Value) && node.Key == "Location")
|
||||
@@ -424,7 +424,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
|
||||
// Fix TD building footprints to not use _ when it's not necessary
|
||||
if (engineVersion < 20160619 && modData.Manifest.Mod.Id == "cnc" && depth == 1)
|
||||
if (engineVersion < 20160619 && modData.Manifest.Id == "cnc" && depth == 1)
|
||||
{
|
||||
var buildings = new List<string>() { "atwr", "obli", "tmpl", "weap", "hand" };
|
||||
if (buildings.Contains(parent.Value.Value) && node.Key == "Location")
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
if (playerDefinitions != null)
|
||||
map.PlayerDefinitions = playerDefinitions;
|
||||
|
||||
map.RequiresMod = modData.Manifest.Mod.Id;
|
||||
map.RequiresMod = modData.Manifest.Id;
|
||||
|
||||
var combinedPath = Platform.ResolvePath(Path.Combine(selectedDirectory.Folder.Name, filename.Text + fileTypes[fileType].Extension));
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
if (mpe != null)
|
||||
mpe.Fade(mpe.Info.MenuEffect);
|
||||
|
||||
menu.Get<LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Mod.Version;
|
||||
menu.Get<LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;
|
||||
|
||||
var hideMenu = false;
|
||||
menu.Get("MENU_BUTTONS").IsVisible = () => !hideMenu;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
enum Mode { Progress, Message, List }
|
||||
|
||||
readonly ModContent content;
|
||||
readonly Dictionary<string, ModContent.ModSource> sources;
|
||||
|
||||
readonly Widget panel;
|
||||
readonly LabelWidget titleLabel;
|
||||
@@ -54,9 +55,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
Mode visible = Mode.Progress;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public InstallFromDiscLogic(Widget widget, ModContent content, Action afterInstall)
|
||||
public InstallFromDiscLogic(Widget widget, ModContent content, Dictionary<string, ModContent.ModSource> sources, Action afterInstall)
|
||||
{
|
||||
this.content = content;
|
||||
this.sources = sources;
|
||||
|
||||
Log.AddChannel("install", "install.log");
|
||||
|
||||
@@ -106,7 +108,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
.Where(v => v.DriveType == DriveType.CDRom && v.IsReady)
|
||||
.Select(v => v.RootDirectory.FullName);
|
||||
|
||||
foreach (var kv in content.Sources)
|
||||
foreach (var kv in sources)
|
||||
{
|
||||
message = "Searching for " + kv.Value.Title;
|
||||
|
||||
@@ -131,12 +133,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
}
|
||||
}
|
||||
|
||||
var sources = content.Packages.Values
|
||||
var missingSources = content.Packages.Values
|
||||
.Where(p => !p.IsInstalled())
|
||||
.SelectMany(p => p.Sources)
|
||||
.Select(d => content.Sources[d]);
|
||||
.Select(d => sources[d]);
|
||||
|
||||
var discs = sources
|
||||
var discs = missingSources
|
||||
.Where(s => s.Type == ModContent.SourceType.Disc)
|
||||
.Select(s => s.Title)
|
||||
.Distinct();
|
||||
@@ -148,7 +150,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
if (Platform.CurrentPlatform == PlatformType.Windows)
|
||||
{
|
||||
var installations = sources
|
||||
var installations = missingSources
|
||||
.Where(s => s.Type == ModContent.SourceType.Install)
|
||||
.Select(s => s.Title)
|
||||
.Distinct();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var panel = widget.Get("INSTALL_MOD_PANEL");
|
||||
|
||||
var mods = ModMetadata.AllMods[modId].RequiresMods.Where(m => !Game.IsModInstalled(m)).Select(m => "{0} ({1})".F(m.Key, m.Value));
|
||||
var mods = Game.Mods[modId].RequiresMods.Where(m => !Game.IsModInstalled(m)).Select(m => "{0} ({1})".F(m.Key, m.Value));
|
||||
var text = string.Join(", ", mods);
|
||||
panel.Get<LabelWidget>("MOD_LIST").Text = text;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
@@ -21,14 +21,32 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
readonly ModContent content;
|
||||
readonly ScrollPanelWidget scrollPanel;
|
||||
readonly Widget template;
|
||||
|
||||
readonly Dictionary<string, ModContent.ModSource> sources = new Dictionary<string, ModContent.ModSource>();
|
||||
readonly Dictionary<string, ModContent.ModDownload> downloads = new Dictionary<string, ModContent.ModDownload>();
|
||||
|
||||
bool discAvailable;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ModContentLogic(Widget widget, string modId, Action onCancel)
|
||||
public ModContentLogic(Widget widget, Manifest mod, ModContent content, Action onCancel)
|
||||
{
|
||||
this.content = content;
|
||||
|
||||
var panel = widget.Get("CONTENT_PANEL");
|
||||
|
||||
content = ModMetadata.AllMods[modId].ModContent;
|
||||
var modFileSystem = new FileSystem.FileSystem(Game.Mods);
|
||||
modFileSystem.LoadFromManifest(mod);
|
||||
|
||||
var sourceYaml = MiniYaml.Load(modFileSystem, content.Sources, null);
|
||||
foreach (var s in sourceYaml)
|
||||
sources.Add(s.Key, new ModContent.ModSource(s.Value));
|
||||
|
||||
var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null);
|
||||
foreach (var d in downloadYaml)
|
||||
downloads.Add(d.Key, new ModContent.ModDownload(d.Value));
|
||||
|
||||
modFileSystem.UnmountAll();
|
||||
|
||||
scrollPanel = panel.Get<ScrollPanelWidget>("PACKAGES");
|
||||
template = scrollPanel.Get<ContainerWidget>("PACKAGE_TEMPLATE");
|
||||
|
||||
@@ -56,6 +74,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
discButton.OnClick = () => Ui.OpenWindow("DISC_INSTALL_PANEL", new WidgetArgs
|
||||
{
|
||||
{ "afterInstall", () => { } },
|
||||
{ "sources", sources },
|
||||
{ "content", content }
|
||||
});
|
||||
|
||||
@@ -87,9 +106,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
requiredWidget.IsVisible = () => p.Value.Required;
|
||||
|
||||
var sourceWidget = container.Get<ImageWidget>("DISC");
|
||||
var sources = p.Value.Sources.Select(s => content.Sources[s].Title).Distinct();
|
||||
var sourceList = sources.JoinWith("\n");
|
||||
var isSourceAvailable = sources.Any();
|
||||
var sourceTitles = p.Value.Sources.Select(s => sources[s].Title).Distinct();
|
||||
var sourceList = sourceTitles.JoinWith("\n");
|
||||
var isSourceAvailable = sourceTitles.Any();
|
||||
sourceWidget.GetTooltipText = () => sourceList;
|
||||
sourceWidget.IsVisible = () => isSourceAvailable;
|
||||
|
||||
@@ -100,10 +119,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
if (downloadEnabled)
|
||||
{
|
||||
var download = content.Downloads[p.Value.Download];
|
||||
var widgetArgs = new WidgetArgs
|
||||
{
|
||||
{ "download", download },
|
||||
{ "download", downloads[p.Value.Download] },
|
||||
{ "onSuccess", () => { } }
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
@@ -17,13 +18,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
public class ModContentPromptLogic : ChromeLogic
|
||||
{
|
||||
[ObjectCreator.UseCtor]
|
||||
public ModContentPromptLogic(Widget widget, string modId, Action continueLoading)
|
||||
public ModContentPromptLogic(Widget widget, Manifest mod, ModContent content, Action continueLoading)
|
||||
{
|
||||
var panel = widget.Get("CONTENT_PROMPT_PANEL");
|
||||
|
||||
var mod = ModMetadata.AllMods[modId];
|
||||
var content = ModMetadata.AllMods[modId].ModContent;
|
||||
|
||||
var headerTemplate = panel.Get<LabelWidget>("HEADER_TEMPLATE");
|
||||
var headerLines = !string.IsNullOrEmpty(content.InstallPromptMessage) ? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n') : new string[0];
|
||||
var headerHeight = 0;
|
||||
@@ -46,7 +44,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
Ui.OpenWindow("CONTENT_PANEL", new WidgetArgs
|
||||
{
|
||||
{ "modId", modId },
|
||||
{ "mod", mod },
|
||||
{ "content", content },
|
||||
{ "onCancel", Ui.CloseWindow }
|
||||
});
|
||||
};
|
||||
@@ -56,9 +55,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
quickButton.Bounds.Y += headerHeight;
|
||||
quickButton.OnClick = () =>
|
||||
{
|
||||
var modFileSystem = new FileSystem.FileSystem(Game.Mods);
|
||||
modFileSystem.LoadFromManifest(mod);
|
||||
var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null);
|
||||
modFileSystem.UnmountAll();
|
||||
|
||||
var download = downloadYaml.FirstOrDefault(n => n.Key == content.QuickDownload);
|
||||
if (download == null)
|
||||
throw new InvalidOperationException("Mod QuickDownload `{0}` definition not found.".F(content.QuickDownload));
|
||||
|
||||
Ui.OpenWindow("PACKAGE_DOWNLOAD_PANEL", new WidgetArgs
|
||||
{
|
||||
{ "download", content.Downloads[content.QuickDownload] },
|
||||
{ "download", new ModContent.ModDownload(download.Value) },
|
||||
{ "onSuccess", continueLoading }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
public MainMenuLogic(Widget widget, World world, ModData modData)
|
||||
{
|
||||
rootMenu = widget;
|
||||
rootMenu.Get<LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Mod.Version;
|
||||
rootMenu.Get<LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;
|
||||
|
||||
// Menu buttons
|
||||
var mainMenu = widget.Get("MAIN_MENU");
|
||||
@@ -90,7 +90,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
// so we can't do this inside the input handler.
|
||||
Game.RunAfterTick(() =>
|
||||
{
|
||||
Game.Settings.Game.PreviousMod = modData.Manifest.Mod.Id;
|
||||
Game.Settings.Game.PreviousMod = modData.Manifest.Id;
|
||||
Game.InitializeMod("modchooser", null);
|
||||
});
|
||||
};
|
||||
@@ -283,9 +283,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
// Send the mod and engine version to support version-filtered news (update prompts)
|
||||
var newsURL = Game.Settings.Game.NewsUrl + "?version={0}&mod={1}&modversion={2}".F(
|
||||
Uri.EscapeUriString(ModMetadata.AllMods["modchooser"].Version),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Id),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Version));
|
||||
Uri.EscapeUriString(Game.Mods["modchooser"].Metadata.Version),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Id),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Metadata.Version));
|
||||
|
||||
// Append system profile data if the player has opted in
|
||||
if (Game.Settings.Debug.SendSystemInformation)
|
||||
|
||||
@@ -24,32 +24,39 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
readonly Widget modList;
|
||||
readonly ButtonWidget modTemplate;
|
||||
readonly ModMetadata[] allMods;
|
||||
readonly Manifest[] allMods;
|
||||
readonly Dictionary<string, Sprite> previews = new Dictionary<string, Sprite>();
|
||||
readonly Dictionary<string, Sprite> logos = new Dictionary<string, Sprite>();
|
||||
readonly Cache<Manifest, ModContent> content = new Cache<Manifest, ModContent>(LoadModContent);
|
||||
|
||||
readonly Widget modChooserPanel;
|
||||
readonly ButtonWidget loadButton;
|
||||
readonly SheetBuilder sheetBuilder;
|
||||
ModMetadata selectedMod;
|
||||
Manifest selectedMod;
|
||||
string selectedAuthor;
|
||||
string selectedDescription;
|
||||
int modOffset = 0;
|
||||
|
||||
static ModContent LoadModContent(Manifest mod)
|
||||
{
|
||||
return mod.Get<ModContent>(Game.ModData.ObjectCreator);
|
||||
}
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ModBrowserLogic(Widget widget, ModData modData)
|
||||
{
|
||||
modChooserPanel = widget;
|
||||
loadButton = modChooserPanel.Get<ButtonWidget>("LOAD_BUTTON");
|
||||
loadButton.OnClick = () => LoadMod(selectedMod);
|
||||
loadButton.IsDisabled = () => selectedMod.Id == modData.Manifest.Mod.Id;
|
||||
loadButton.IsDisabled = () => selectedMod.Id == modData.Manifest.Id;
|
||||
|
||||
var contentButton = modChooserPanel.Get<ButtonWidget>("CONFIGURE_BUTTON");
|
||||
contentButton.IsDisabled = () => selectedMod.ModContent == null;
|
||||
contentButton.OnClick = () =>
|
||||
{
|
||||
var widgetArgs = new WidgetArgs
|
||||
{
|
||||
{ "modId", selectedMod.Id },
|
||||
{ "mod", selectedMod },
|
||||
{ "content", content[selectedMod] },
|
||||
{ "onCancel", () => { } }
|
||||
};
|
||||
|
||||
@@ -62,9 +69,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
modTemplate = modList.Get<ButtonWidget>("MOD_TEMPLATE");
|
||||
|
||||
modChooserPanel.Get<LabelWidget>("MOD_DESC").GetText = () => selectedDescription;
|
||||
modChooserPanel.Get<LabelWidget>("MOD_TITLE").GetText = () => selectedMod.Title;
|
||||
modChooserPanel.Get<LabelWidget>("MOD_TITLE").GetText = () => selectedMod.Metadata.Title;
|
||||
modChooserPanel.Get<LabelWidget>("MOD_AUTHOR").GetText = () => selectedAuthor;
|
||||
modChooserPanel.Get<LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Version;
|
||||
modChooserPanel.Get<LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Metadata.Version;
|
||||
|
||||
var prevMod = modChooserPanel.Get<ButtonWidget>("PREV_MOD");
|
||||
prevMod.OnClick = () => { modOffset -= 1; RebuildModList(); };
|
||||
@@ -82,8 +89,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
};
|
||||
|
||||
sheetBuilder = new SheetBuilder(SheetType.BGRA);
|
||||
allMods = ModMetadata.AllMods.Values.Where(m => !m.Hidden)
|
||||
.OrderBy(m => m.Title)
|
||||
allMods = Game.Mods.Values.Where(m => !m.Metadata.Hidden)
|
||||
.OrderBy(m => m.Metadata.Title)
|
||||
.ToArray();
|
||||
|
||||
// Load preview images, and eat any errors
|
||||
@@ -91,7 +98,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var stream = ModMetadata.AllMods[mod.Id].Package.GetStream("preview.png"))
|
||||
using (var stream = mod.Package.GetStream("preview.png"))
|
||||
using (var preview = new Bitmap(stream))
|
||||
if (preview.Width == 296 && preview.Height == 196)
|
||||
previews.Add(mod.Id, sheetBuilder.Add(preview));
|
||||
@@ -100,7 +107,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
try
|
||||
{
|
||||
using (var stream = ModMetadata.AllMods[mod.Id].Package.GetStream("logo.png"))
|
||||
using (var stream = mod.Package.GetStream("logo.png"))
|
||||
using (var logo = new Bitmap(stream))
|
||||
if (logo.Width == 96 && logo.Height == 96)
|
||||
logos.Add(mod.Id, sheetBuilder.Add(logo));
|
||||
@@ -108,9 +115,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
ModMetadata initialMod;
|
||||
ModMetadata.AllMods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
|
||||
SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : ModMetadata.AllMods["ra"]);
|
||||
Manifest initialMod;
|
||||
Game.Mods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
|
||||
SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : Game.Mods["ra"]);
|
||||
|
||||
RebuildModList();
|
||||
}
|
||||
@@ -146,7 +153,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
SelectMod(mod);
|
||||
};
|
||||
|
||||
item.TooltipText = mod.Title;
|
||||
item.TooltipText = mod.Metadata.Title;
|
||||
|
||||
if (j < 9)
|
||||
item.Key = new Hotkey((Keycode)((int)Keycode.NUMBER_1 + j), Modifiers.None);
|
||||
@@ -160,23 +167,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
}
|
||||
}
|
||||
|
||||
void SelectMod(ModMetadata mod)
|
||||
void SelectMod(Manifest mod)
|
||||
{
|
||||
selectedMod = mod;
|
||||
selectedAuthor = "By " + (mod.Author ?? "unknown author");
|
||||
selectedDescription = (mod.Description ?? "").Replace("\\n", "\n");
|
||||
selectedAuthor = "By " + (mod.Metadata.Author ?? "unknown author");
|
||||
selectedDescription = (mod.Metadata.Description ?? "").Replace("\\n", "\n");
|
||||
var selectedIndex = Array.IndexOf(allMods, mod);
|
||||
if (selectedIndex - modOffset > 4)
|
||||
modOffset = selectedIndex - 4;
|
||||
}
|
||||
|
||||
void LoadMod(ModMetadata mod)
|
||||
void LoadMod(Manifest mod)
|
||||
{
|
||||
if (!Game.IsModInstalled(mod.Id))
|
||||
var modId = mod.Id;
|
||||
if (!Game.IsModInstalled(modId))
|
||||
{
|
||||
var widgetArgs = new WidgetArgs
|
||||
{
|
||||
{ "modId", mod.Id }
|
||||
{ "mod", selectedMod },
|
||||
{ "content", content[selectedMod] },
|
||||
};
|
||||
|
||||
Ui.OpenWindow("INSTALL_MOD_PANEL", widgetArgs);
|
||||
@@ -188,8 +197,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var widgetArgs = new WidgetArgs
|
||||
{
|
||||
{ "continueLoading", () =>
|
||||
Game.RunAfterTick(() => Game.InitializeMod(mod.Id, new Arguments())) },
|
||||
{ "modId", mod.Id }
|
||||
Game.RunAfterTick(() => Game.InitializeMod(modId, new Arguments())) },
|
||||
{ "mod", selectedMod },
|
||||
{ "content", content[selectedMod] },
|
||||
};
|
||||
|
||||
Ui.OpenWindow("CONTENT_PROMPT_PANEL", widgetArgs);
|
||||
@@ -201,13 +211,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
Ui.CloseWindow();
|
||||
sheetBuilder.Dispose();
|
||||
Game.InitializeMod(mod.Id, null);
|
||||
Game.InitializeMod(modId, null);
|
||||
});
|
||||
}
|
||||
|
||||
static bool IsModInstalled(ModMetadata mod)
|
||||
bool IsModInstalled(Manifest mod)
|
||||
{
|
||||
return mod.ModContent.Packages
|
||||
return content[mod].Packages
|
||||
.Where(p => p.Value.Required)
|
||||
.All(p => p.Value.TestFiles.All(f => File.Exists(Platform.ResolvePath(f))));
|
||||
}
|
||||
|
||||
@@ -316,9 +316,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
};
|
||||
|
||||
var queryURL = Game.Settings.Server.MasterServer + "games?version={0}&mod={1}&modversion={2}".F(
|
||||
Uri.EscapeUriString(ModMetadata.AllMods["modchooser"].Version),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Id),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Mod.Version));
|
||||
Uri.EscapeUriString(Game.Mods["modchooser"].Metadata.Version),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Id),
|
||||
Uri.EscapeUriString(Game.ModData.Manifest.Metadata.Version));
|
||||
|
||||
currentQuery = new Download(queryURL, _ => { }, onComplete);
|
||||
}
|
||||
@@ -330,7 +330,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
return 0;
|
||||
|
||||
// Games for the current mod+version are sorted first
|
||||
if (testEntry.ModId == modData.Manifest.Mod.Id)
|
||||
if (testEntry.ModId == modData.Manifest.Id)
|
||||
return 2;
|
||||
|
||||
// Followed by games for different mods that are joinable
|
||||
|
||||
@@ -59,8 +59,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
replayList = panel.Get<ScrollPanelWidget>("REPLAY_LIST");
|
||||
var template = panel.Get<ScrollItemWidget>("REPLAY_TEMPLATE");
|
||||
|
||||
var mod = modData.Manifest.Mod;
|
||||
var dir = Platform.ResolvePath("^", "Replays", mod.Id, mod.Version);
|
||||
var mod = modData.Manifest;
|
||||
var dir = Platform.ResolvePath("^", "Replays", mod.Id, mod.Metadata.Version);
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
ThreadPool.QueueUserWorkItem(_ => LoadReplays(dir, template));
|
||||
|
||||
@@ -34,10 +34,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
if (mod == null)
|
||||
return IncompatibleReplayDialog("unknown mod", mod, onCancel);
|
||||
|
||||
var allMods = ModMetadata.AllMods;
|
||||
if (!allMods.ContainsKey(mod))
|
||||
if (!Game.Mods.ContainsKey(mod))
|
||||
return IncompatibleReplayDialog("unavailable mod", mod, onCancel);
|
||||
else if (allMods[mod].Version != version)
|
||||
|
||||
if (Game.Mods[mod].Metadata.Version != version)
|
||||
return IncompatibleReplayDialog("incompatible version", version, onCancel);
|
||||
|
||||
if (replayMeta.GameInfo.MapPreview.Status != MapStatus.Available)
|
||||
|
||||
Reference in New Issue
Block a user