#region Copyright & License Information /* * Copyright (c) The OpenRA Developers and Contributors * 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; using System.Collections.Frozen; using System.Collections.Generic; using System.Collections.Immutable; using System.Globalization; using System.Linq; using System.Text; using OpenRA.Mods.Common.MapGenerator; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; namespace OpenRA.Mods.Common.UtilityCommands { sealed class FuzzMapGeneratorCommand : IUtilityCommand { string IUtilityCommand.Name => "--fuzz-map-generator"; sealed class Configuration { public const string TilesetVariable = "__tileset__"; public const string SizeVariable = "__size__"; public readonly string MapGeneratorType; public readonly bool NoDefaults; public readonly bool DryRun; public readonly long Skip; public readonly int Shard; public readonly int ShardCount; public readonly ImmutableArray Variables; public readonly FrozenDictionary> Choices; Configuration( string mapGeneratorName, bool noDefaults, bool dryRun, long skip, int shard, int shardCount, ImmutableArray variables, FrozenDictionary> choices) { MapGeneratorType = mapGeneratorName; NoDefaults = noDefaults; DryRun = dryRun; Skip = skip; Shard = shard; ShardCount = shardCount; Variables = variables; Choices = choices; } public static Configuration Parse(string[] args) { string mapGeneratorName = null; var noDefaults = false; var dryRun = false; long skip = 0; var shard = 0; var shardCount = 1; var variables = new List(); var choices = new Dictionary>(); bool AddVariable(string variable, string choicesStr) { if (choices.ContainsKey(variable)) return false; variables.Add(variable); choices.Add(variable, choicesStr.Split(',').ToImmutableArray()); return true; } foreach (var arg in args) { var parts = arg.Split('='); switch (parts[0]) { case "--fuzz-map-generator": break; case "--no-defaults": if (parts.Length != 1) return null; noDefaults = true; break; case "--dry-run": if (parts.Length != 1) return null; dryRun = true; break; case "--skip": if (parts.Length != 2 || skip != 0) return null; if (!Exts.TryParseInt64Invariant(parts[1], out skip)) return null; break; case "--shard": if (parts.Length != 2 || shardCount != 1) return null; var shardParts = parts[1].Split('/'); if (!Exts.TryParseInt32Invariant(shardParts[0], out shard)) return null; if (!Exts.TryParseInt32Invariant(shardParts[1], out shardCount)) return null; if (shard < 0 || shard >= shardCount) return null; break; case "--generator": if (parts.Length != 2 || mapGeneratorName != null) return null; mapGeneratorName = parts[1]; break; case "--tilesets": if (parts.Length != 2 || !AddVariable(TilesetVariable, parts[1])) return null; break; case "--sizes": if (parts.Length != 2 || !AddVariable(SizeVariable, parts[1])) return null; break; case "--choices": if (parts.Length != 3 || !AddVariable(parts[1], parts[2])) return null; break; default: Console.Error.WriteLine($"Unrecognized argument {arg}"); return null; } } if (mapGeneratorName == null) { Console.Error.WriteLine("--generator is mandatory"); return null; } if (!choices.ContainsKey(TilesetVariable)) { Console.Error.WriteLine("--tilesets is mandatory"); return null; } if (!choices.ContainsKey(SizeVariable)) { Console.Error.WriteLine("--sizes is mandatory"); return null; } return new( mapGeneratorName, noDefaults, dryRun, skip, shard, shardCount, variables.ToImmutableArray(), choices.ToFrozenDictionary()); } } bool IUtilityCommand.ValidateArguments(string[] args) { return Configuration.Parse(args) != null; } [Desc( "--generator=TYPE " + "(--choices=