public string Serialize() { var root = new List <MiniYamlNode>() { new MiniYamlNode("Protocol", ProtocolVersion.ToString()) }; foreach (var field in SerializeFields) { root.Add(FieldSaver.SaveField(this, field)); } if (Arguments != null) { var argumentsNode = new MiniYaml(""); var i = 0; foreach (var argument in Arguments) { argumentsNode.Nodes.Add(new MiniYamlNode("Argument@" + i++, FieldSaver.Save(argument))); } root.Add(new MiniYamlNode("Arguments", argumentsNode)); } return(new MiniYaml("", root) .ToLines("LocalizedMessage") .JoinWith("\n")); }
public static void ExtractTraitDocs(string[] args) { Game.modData = new ModData(args[1]); 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); Console.WriteLine(); var toc = new StringBuilder(); var doc = new StringBuilder(); foreach (var t in Game.modData.ObjectCreator.GetTypesImplementing <ITraitInfo>().OrderBy(t => t.Namespace)) { if (t.ContainsGenericParameters || t.IsAbstract) { continue; // skip helpers like TraitInfo<T> } var traitName = t.Name.EndsWith("Info") ? t.Name.Substring(0, t.Name.Length - 4) : t.Name; toc.AppendLine("* [{0}](#{1})".F(traitName, traitName.ToLowerInvariant())); var traitDescLines = t.GetCustomAttributes <DescAttribute>(false).SelectMany(d => d.Lines); doc.AppendLine(); doc.AppendLine("### {0}".F(traitName)); foreach (var line in traitDescLines) { doc.AppendLine(line); } var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); if (!fields.Any()) { continue; } doc.AppendLine("<table>"); doc.AppendLine("<tr><th>Property</th><th>Default Value</th><th>Type</th><th>Description</th></tr>"); var liveTraitInfo = Game.modData.ObjectCreator.CreateBasic(t); foreach (var f in fields) { var fieldDescLines = f.GetCustomAttributes <DescAttribute>(true).SelectMany(d => d.Lines); var fieldType = FriendlyTypeName(f.FieldType); var defaultValue = FieldSaver.SaveField(liveTraitInfo, f.Name).Value.Value; doc.Append("<tr><td>{0}</td><td>{1}</td><td>{2}</td>".F(f.Name, defaultValue, fieldType)); doc.Append("<td>"); foreach (var line in fieldDescLines) { doc.Append(line); } doc.AppendLine("</td></tr>"); } doc.AppendLine("</table>"); } Console.Write(toc.ToString()); Console.Write(doc.ToString()); }
public static void ExtractTraitDocs(string[] args) { Game.modData = new ModData(args[1]); FileSystem.LoadFromManifest(Game.modData.Manifest); Rules.LoadRules(Game.modData.Manifest, new Map()); Console.WriteLine("## Documentation"); Console.WriteLine( "This documentation is aimed at modders and contributors of OpenRA. 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 on {0}. " + "Type `make docs` to create a new one. A copy of this is uploaded to https://github.com/OpenRA/OpenRA/wiki/Traits " + "as well as compiled to HTML and shipped with every release during the automated packaging process.", DateTime.Now); Console.WriteLine(); Console.WriteLine("```yaml"); Console.WriteLine(); foreach (var t in Game.modData.ObjectCreator.GetTypesImplementing <ITraitInfo>()) { if (t.ContainsGenericParameters || t.IsAbstract) { continue; // skip helpers like TraitInfo<T> } var traitName = t.Name.EndsWith("Info") ? t.Name.Substring(0, t.Name.Length - 4) : t.Name; var traitDescLines = t.GetCustomAttributes <DescAttribute>(false).SelectMany(d => d.Lines); Console.WriteLine("\t{0}:{1}", traitName, traitDescLines.Count() == 1 ? " # " + traitDescLines.First() : ""); if (traitDescLines.Count() >= 2) { foreach (var line in traitDescLines) { Console.WriteLine("\t\t# {0}", line); } } var liveTraitInfo = Game.modData.ObjectCreator.CreateBasic(t); foreach (var f in t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)) { var fieldDescLines = f.GetCustomAttributes <DescAttribute>(true).SelectMany(d => d.Lines); var fieldType = FriendlyTypeName(f.FieldType); var defaultValue = FieldSaver.SaveField(liveTraitInfo, f.Name).Value.Value; Console.WriteLine("\t\t{0}: {1} # Type: {2}{3}", f.Name, defaultValue, fieldType, fieldDescLines.Count() == 1 ? ". " + fieldDescLines.First() : ""); if (fieldDescLines.Count() >= 2) { foreach (var line in fieldDescLines) { Console.WriteLine("\t\t# {0}", line); } } } } Console.WriteLine(); Console.WriteLine("```"); }
public string ToPOSTData(bool lanGame) { var root = new List <MiniYamlNode>() { new MiniYamlNode("Protocol", ProtocolVersion.ToString()) }; foreach (var field in SerializeFields) { root.Add(FieldSaver.SaveField(this, field)); } if (lanGame) { // Add fields that are normally generated by the master server // LAN games overload the Id with a GUID string (rather than an ID) to allow deduplication root.Add(new MiniYamlNode("Id", Platform.SessionGUID.ToString())); root.Add(new MiniYamlNode("Players", Clients.Count(c => !c.IsBot && !c.IsSpectator).ToString())); root.Add(new MiniYamlNode("Spectators", Clients.Count(c => c.IsSpectator).ToString())); root.Add(new MiniYamlNode("Bots", Clients.Count(c => c.IsBot).ToString())); // Included for backwards compatibility with older clients that don't support separated Mod/Version. root.Add(new MiniYamlNode("Mods", Mod + "@" + Version)); } var clientsNode = new MiniYaml(""); var i = 0; foreach (var c in Clients) { clientsNode.Nodes.Add(new MiniYamlNode("Client@" + (i++).ToString(), FieldSaver.Save(c))); } root.Add(new MiniYamlNode("Clients", clientsNode)); return(new MiniYaml("", root) .ToLines("Game") .JoinWith("\n")); }
void IUtilityCommand.Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. Game.ModData = utility.ModData; var version = utility.ModData.Manifest.Metadata.Version; if (args.Length > 1) { version = args[1]; } 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 {version} of OpenRA."); Console.WriteLine(); var doc = new StringBuilder(); var currentNamespace = ""; foreach (var t in Game.ModData.ObjectCreator.GetTypesImplementing <TraitInfo>().OrderBy(t => t.Namespace)) { if (t.ContainsGenericParameters || t.IsAbstract) { continue; // skip helpers like TraitInfo<T> } if (currentNamespace != t.Namespace) { currentNamespace = t.Namespace; doc.AppendLine(); doc.AppendLine($"## {currentNamespace}"); } var traitName = t.Name.EndsWith("Info") ? t.Name.Substring(0, t.Name.Length - 4) : t.Name; var traitDescLines = t.GetCustomAttributes <DescAttribute>(false).SelectMany(d => d.Lines); doc.AppendLine(); doc.AppendLine($"### {traitName}"); foreach (var line in traitDescLines) { doc.AppendLine(line); } var requires = RequiredTraitTypes(t); var reqCount = requires.Length; if (reqCount > 0) { if (t.HasAttribute <DescAttribute>()) { doc.AppendLine(); } doc.Append($"Requires trait{(reqCount > 1 ? "s" : "")}: "); var i = 0; foreach (var require in requires) { var n = require.Name; var name = n.EndsWith("Info") ? n.Remove(n.Length - 4, 4) : n; doc.Append($"[`{name}`](#{name.ToLowerInvariant()}){(i + 1 == reqCount ? ".\n" : ", ")}"); i++; } } var infos = FieldLoader.GetTypeLoadInfo(t); if (!infos.Any()) { continue; } doc.AppendLine(); doc.AppendLine("| Property | Default Value | Type | Description |"); doc.AppendLine("| -------- | --------------| ---- | ----------- |"); var liveTraitInfo = Game.ModData.ObjectCreator.CreateBasic(t); foreach (var info in infos) { var fieldDescLines = info.Field.GetCustomAttributes <DescAttribute>(true).SelectMany(d => d.Lines); var fieldType = Util.FriendlyTypeName(info.Field.FieldType); var loadInfo = info.Field.GetCustomAttributes <FieldLoader.SerializeAttribute>(true).FirstOrDefault(); var defaultValue = loadInfo != null && loadInfo.Required ? "*(required)*" : FieldSaver.SaveField(liveTraitInfo, info.Field.Name).Value.Value; doc.Append($"| {info.YamlName} | {defaultValue} | {fieldType} | "); foreach (var line in fieldDescLines) { doc.Append(line + " "); } doc.AppendLine("|"); } } Console.Write(doc.ToString()); }
public string Serialize() { var data = new List <MiniYamlNode>(); data.Add(new MiniYamlNode("Handshake", null, new string[] { "Mod", "Version", "Password" }.Select(p => FieldSaver.SaveField(this, p)).ToList())); data.Add(new MiniYamlNode("Client", FieldSaver.Save(Client))); return(data.WriteToString()); }
public void Run(ModData modData, string[] args) { // HACK: The engine code assumes that Game.modData is set. Game.ModData = 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); Console.WriteLine(); var toc = new StringBuilder(); var doc = new StringBuilder(); var currentNamespace = ""; foreach (var t in Game.ModData.ObjectCreator.GetTypesImplementing <ITraitInfo>().OrderBy(t => t.Namespace)) { if (t.ContainsGenericParameters || t.IsAbstract) { continue; // skip helpers like TraitInfo<T> } if (currentNamespace != t.Namespace) { currentNamespace = t.Namespace; doc.AppendLine(); doc.AppendLine("## {0}".F(currentNamespace)); toc.AppendLine("* [{0}](#{1})".F(currentNamespace, currentNamespace.Replace(".", "").ToLowerInvariant())); } var traitName = t.Name.EndsWith("Info") ? t.Name.Substring(0, t.Name.Length - 4) : t.Name; toc.AppendLine(" * [{0}](#{1})".F(traitName, traitName.ToLowerInvariant())); var traitDescLines = t.GetCustomAttributes <DescAttribute>(false).SelectMany(d => d.Lines); doc.AppendLine(); doc.AppendLine("### {0}".F(traitName)); foreach (var line in traitDescLines) { doc.AppendLine(line); } var requires = RequiredTraitTypes(t); var reqCount = requires.Length; if (reqCount > 0) { if (t.HasAttribute <DescAttribute>()) { doc.AppendLine(); } doc.Append("Requires trait{0}: ".F(reqCount > 1 ? "s" : "")); var i = 0; foreach (var require in requires) { var n = require.Name; var name = n.EndsWith("Info") ? n.Remove(n.Length - 4, 4) : n; doc.Append("[`{0}`](#{1}){2}".F(name, name.ToLowerInvariant(), i + 1 == reqCount ? ".\n" : ", ")); i++; } } var infos = FieldLoader.GetTypeLoadInfo(t); if (!infos.Any()) { continue; } doc.AppendLine("<table>"); doc.AppendLine("<tr><th>Property</th><th>Default Value</th><th>Type</th><th>Description</th></tr>"); var liveTraitInfo = Game.ModData.ObjectCreator.CreateBasic(t); foreach (var info in infos) { var fieldDescLines = info.Field.GetCustomAttributes <DescAttribute>(true).SelectMany(d => d.Lines); var fieldType = FriendlyTypeName(info.Field.FieldType); var loadInfo = info.Field.GetCustomAttributes <FieldLoader.SerializeAttribute>(true).FirstOrDefault(); var defaultValue = loadInfo != null && loadInfo.Required ? "<em>(required)</em>" : FieldSaver.SaveField(liveTraitInfo, info.Field.Name).Value.Value; doc.Append("<tr><td>{0}</td><td>{1}</td><td>{2}</td>".F(info.YamlName, defaultValue, fieldType)); doc.Append("<td>"); foreach (var line in fieldDescLines) { doc.Append(line + " "); } doc.AppendLine("</td></tr>"); } doc.AppendLine("</table>"); } Console.Write(toc.ToString()); Console.Write(doc.ToString()); }
void IUtilityCommand.Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. Game.ModData = utility.ModData; var version = utility.ModData.Manifest.Metadata.Version; if (args.Length > 1) { version = args[1]; } Console.WriteLine( "This documentation is aimed at modders. It displays a template for weapon definitions " + "as well as its contained types (warheads and projectiles) 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.", version); Console.WriteLine(); var toc = new StringBuilder(); var doc = new StringBuilder(); var currentNamespace = ""; var objectCreator = utility.ModData.ObjectCreator; var weaponInfo = objectCreator.GetTypesImplementing <WeaponInfo>(); var warheads = objectCreator.GetTypesImplementing <IWarhead>().OrderBy(t => t.Namespace); var projectiles = objectCreator.GetTypesImplementing <IProjectileInfo>().OrderBy(t => t.Namespace); var weaponTypes = Enumerable.Concat(weaponInfo, Enumerable.Concat(projectiles, warheads)); foreach (var t in weaponTypes) { // skip helpers like TraitInfo<T> if (t.ContainsGenericParameters || t.IsAbstract) { continue; } if (currentNamespace != t.Namespace) { currentNamespace = t.Namespace; doc.AppendLine(); doc.AppendLine("## {0}".F(currentNamespace)); toc.AppendLine("* [{0}](#{1})".F(currentNamespace, currentNamespace.Replace(".", "").ToLowerInvariant())); } var traitName = t.Name.EndsWith("Info") ? t.Name.Substring(0, t.Name.Length - 4) : t.Name; toc.AppendLine(" * [{0}](#{1})".F(traitName, traitName.ToLowerInvariant())); doc.AppendLine(); doc.AppendLine("### {0}".F(traitName)); var traitDescLines = t.GetCustomAttributes <DescAttribute>(false).SelectMany(d => d.Lines); foreach (var line in traitDescLines) { doc.AppendLine(line); } var infos = FieldLoader.GetTypeLoadInfo(t); if (!infos.Any()) { continue; } doc.AppendLine("<table>"); doc.AppendLine("<tr><th>Property</th><th>Default Value</th><th>Type</th><th>Description</th></tr>"); var liveTraitInfo = t == typeof(WeaponInfo) ? null : objectCreator.CreateBasic(t); foreach (var info in infos) { var fieldDescLines = info.Field.GetCustomAttributes <DescAttribute>(true).SelectMany(d => d.Lines); var fieldType = Util.FriendlyTypeName(info.Field.FieldType); var defaultValue = liveTraitInfo == null ? "" : FieldSaver.SaveField(liveTraitInfo, info.Field.Name).Value.Value; doc.Append("<tr><td>{0}</td><td>{1}</td><td>{2}</td>".F(info.YamlName, defaultValue, fieldType)); doc.Append("<td>"); foreach (var line in fieldDescLines) { doc.Append(line + " "); } doc.AppendLine("</td></tr>"); } doc.AppendLine("</table>"); } Console.Write(toc.ToString()); Console.Write(doc.ToString()); }