public HSLColor FromHex(string value) { Color rgb; if (HSLColor.TryParseRGB(value, out rgb)) { return(new HSLColor(rgb)); } throw new LuaException("Invalid rrggbb[aa] hex string."); }
internal static void UpgradeMapFormat(ModData modData, IReadWritePackage package) { if (package == null) { return; } var yamlStream = package.GetStream("map.yaml"); if (yamlStream == null) { return; } var yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, package.Name)); var nd = yaml.ToDictionary(); var mapFormat = FieldLoader.GetValue <int>("MapFormat", nd["MapFormat"].Value); if (mapFormat < 6) { throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(mapFormat, package.Name)); } // Format 6 -> 7 combined the Selectable and UseAsShellmap flags into the Class enum if (mapFormat < 7) { MiniYaml useAsShellmap; if (nd.TryGetValue("UseAsShellmap", out useAsShellmap) && bool.Parse(useAsShellmap.Value)) { yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("Shellmap"))); } else if (nd["Type"].Value == "Mission" || nd["Type"].Value == "Campaign") { yaml.Nodes.Add(new MiniYamlNode("Visibility", new MiniYaml("MissionSelector"))); } } // Format 7 -> 8 replaced normalized HSL triples with rgb(a) hex colors if (mapFormat < 8) { var players = yaml.Nodes.FirstOrDefault(n => n.Key == "Players"); if (players != null) { bool noteHexColors = false; bool noteColorRamp = false; foreach (var player in players.Value.Nodes) { var colorRampNode = player.Value.Nodes.FirstOrDefault(n => n.Key == "ColorRamp"); if (colorRampNode != null) { Color dummy; var parts = colorRampNode.Value.Value.Split(','); if (parts.Length == 3 || parts.Length == 4) { // Try to convert old normalized HSL value to a rgb hex color try { HSLColor color = new HSLColor( (byte)Exts.ParseIntegerInvariant(parts[0].Trim()).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[1].Trim()).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[2].Trim()).Clamp(0, 255)); colorRampNode.Value.Value = FieldSaver.FormatValue(color); noteHexColors = true; } catch (Exception) { throw new InvalidDataException("Invalid ColorRamp value.\n File: " + package.Name); } } else if (parts.Length != 1 || !HSLColor.TryParseRGB(parts[0], out dummy)) { throw new InvalidDataException("Invalid ColorRamp value.\n File: " + package.Name); } colorRampNode.Key = "Color"; noteColorRamp = true; } } if (noteHexColors) { Console.WriteLine("ColorRamp is now called Color and uses rgb(a) hex value - rrggbb[aa]."); } else if (noteColorRamp) { Console.WriteLine("ColorRamp is now called Color."); } } } // Format 8 -> 9 moved map options and videos from the map file itself to traits if (mapFormat < 9) { var rules = yaml.Nodes.FirstOrDefault(n => n.Key == "Rules"); var worldNode = rules.Value.Nodes.FirstOrDefault(n => n.Key == "World"); if (worldNode == null) { worldNode = new MiniYamlNode("World", new MiniYaml("", new List <MiniYamlNode>())); } var playerNode = rules.Value.Nodes.FirstOrDefault(n => n.Key == "Player"); if (playerNode == null) { playerNode = new MiniYamlNode("Player", new MiniYaml("", new List <MiniYamlNode>())); } var visibilityNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Visibility"); if (visibilityNode != null) { var visibility = FieldLoader.GetValue <MapVisibility>("Visibility", visibilityNode.Value.Value); if (visibility.HasFlag(MapVisibility.MissionSelector)) { var missionData = new MiniYamlNode("MissionData", new MiniYaml("", new List <MiniYamlNode>())); worldNode.Value.Nodes.Add(missionData); var description = yaml.Nodes.FirstOrDefault(n => n.Key == "Description"); if (description != null) { missionData.Value.Nodes.Add(new MiniYamlNode("Briefing", description.Value.Value)); } var videos = yaml.Nodes.FirstOrDefault(n => n.Key == "Videos"); if (videos != null && videos.Value.Nodes.Any()) { var backgroundVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "BackgroundInfo"); if (backgroundVideo != null) { missionData.Value.Nodes.Add(new MiniYamlNode("BackgroundVideo", backgroundVideo.Value.Value)); } var briefingVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "Briefing"); if (briefingVideo != null) { missionData.Value.Nodes.Add(new MiniYamlNode("BriefingVideo", briefingVideo.Value.Value)); } var startVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameStart"); if (startVideo != null) { missionData.Value.Nodes.Add(new MiniYamlNode("StartVideo", startVideo.Value.Value)); } var winVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameWon"); if (winVideo != null) { missionData.Value.Nodes.Add(new MiniYamlNode("WinVideo", winVideo.Value.Value)); } var lossVideo = videos.Value.Nodes.FirstOrDefault(n => n.Key == "GameLost"); if (lossVideo != null) { missionData.Value.Nodes.Add(new MiniYamlNode("LossVideo", lossVideo.Value.Value)); } } } } var mapOptions = yaml.Nodes.FirstOrDefault(n => n.Key == "Options"); if (mapOptions != null) { var cheats = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Cheats"); if (cheats != null) { worldNode.Value.Nodes.Add(new MiniYamlNode("DeveloperMode", new MiniYaml("", new List <MiniYamlNode>() { new MiniYamlNode("Locked", "True"), new MiniYamlNode("Enabled", cheats.Value.Value) }))); } var crates = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Crates"); if (crates != null && !worldNode.Value.Nodes.Any(n => n.Key == "-CrateSpawner")) { if (!FieldLoader.GetValue <bool>("crates", crates.Value.Value)) { worldNode.Value.Nodes.Add(new MiniYamlNode("-CrateSpawner", new MiniYaml(""))); } } var creeps = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Creeps"); if (creeps != null) { worldNode.Value.Nodes.Add(new MiniYamlNode("MapCreeps", new MiniYaml("", new List <MiniYamlNode>() { new MiniYamlNode("Locked", "True"), new MiniYamlNode("Enabled", creeps.Value.Value) }))); } var fog = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Fog"); var shroud = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Shroud"); if (fog != null || shroud != null) { var shroudNode = new MiniYamlNode("Shroud", new MiniYaml("", new List <MiniYamlNode>())); playerNode.Value.Nodes.Add(shroudNode); if (fog != null) { shroudNode.Value.Nodes.Add(new MiniYamlNode("FogLocked", "True")); shroudNode.Value.Nodes.Add(new MiniYamlNode("FogEnabled", fog.Value.Value)); } if (shroud != null) { var enabled = FieldLoader.GetValue <bool>("shroud", shroud.Value.Value); shroudNode.Value.Nodes.Add(new MiniYamlNode("ExploredMapLocked", "True")); shroudNode.Value.Nodes.Add(new MiniYamlNode("ExploredMapEnabled", FieldSaver.FormatValue(!enabled))); } } var allyBuildRadius = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "AllyBuildRadius"); if (allyBuildRadius != null) { worldNode.Value.Nodes.Add(new MiniYamlNode("MapBuildRadius", new MiniYaml("", new List <MiniYamlNode>() { new MiniYamlNode("AllyBuildRadiusLocked", "True"), new MiniYamlNode("AllyBuildRadiusEnabled", allyBuildRadius.Value.Value) }))); } var startingCash = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "StartingCash"); if (startingCash != null) { playerNode.Value.Nodes.Add(new MiniYamlNode("PlayerResources", new MiniYaml("", new List <MiniYamlNode>() { new MiniYamlNode("DefaultCashLocked", "True"), new MiniYamlNode("DefaultCash", startingCash.Value.Value) }))); } var startingUnits = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "ConfigurableStartingUnits"); if (startingUnits != null && !worldNode.Value.Nodes.Any(n => n.Key == "-SpawnMPUnits")) { worldNode.Value.Nodes.Add(new MiniYamlNode("SpawnMPUnits", new MiniYaml("", new List <MiniYamlNode>() { new MiniYamlNode("Locked", "True"), }))); } var techLevel = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "TechLevel"); var difficulties = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "Difficulties"); var shortGame = mapOptions.Value.Nodes.FirstOrDefault(n => n.Key == "ShortGame"); if (techLevel != null || difficulties != null || shortGame != null) { var optionsNode = new MiniYamlNode("MapOptions", new MiniYaml("", new List <MiniYamlNode>())); worldNode.Value.Nodes.Add(optionsNode); if (techLevel != null) { optionsNode.Value.Nodes.Add(new MiniYamlNode("TechLevelLocked", "True")); optionsNode.Value.Nodes.Add(new MiniYamlNode("TechLevel", techLevel.Value.Value)); } if (difficulties != null) { optionsNode.Value.Nodes.Add(new MiniYamlNode("Difficulties", difficulties.Value.Value)); } if (shortGame != null) { optionsNode.Value.Nodes.Add(new MiniYamlNode("ShortGameLocked", "True")); optionsNode.Value.Nodes.Add(new MiniYamlNode("ShortGameEnabled", shortGame.Value.Value)); } } } if (worldNode.Value.Nodes.Any() && !rules.Value.Nodes.Contains(worldNode)) { rules.Value.Nodes.Add(worldNode); } if (playerNode.Value.Nodes.Any() && !rules.Value.Nodes.Contains(playerNode)) { rules.Value.Nodes.Add(playerNode); } } // Format 9 -> 10 moved smudges to SmudgeLayer, and uses map.png for all maps if (mapFormat < 10) { ExtractSmudges(yaml); if (package.Contains("map.png")) { yaml.Nodes.Add(new MiniYamlNode("LockPreview", new MiniYaml("True"))); } } // Format 10 -> 11 replaced the single map type field with a list of categories if (mapFormat < 11) { var type = yaml.Nodes.First(n => n.Key == "Type"); yaml.Nodes.Add(new MiniYamlNode("Categories", type.Value)); yaml.Nodes.Remove(type); } if (mapFormat < Map.SupportedMapFormat) { yaml.Nodes.First(n => n.Key == "MapFormat").Value = new MiniYaml(Map.SupportedMapFormat.ToString()); Console.WriteLine("Converted {0} to MapFormat {1}.", package.Name, Map.SupportedMapFormat); } package.Update("map.yaml", Encoding.UTF8.GetBytes(yaml.Nodes.WriteToString())); }
public static object GetValue(string fieldName, Type fieldType, MiniYaml yaml, MemberInfo field) { var value = yaml.Value; if (value != null) { value = value.Trim(); } if (fieldType == typeof(int)) { int res; if (Exts.TryParseIntegerInvariant(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(ushort)) { ushort res; if (ushort.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } if (fieldType == typeof(long)) { long res; if (long.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float)) { float res; if (value != null && float.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { return(res * (value.Contains('%') ? 0.01f : 1f)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(decimal)) { decimal res; if (value != null && decimal.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { return(res * (value.Contains('%') ? 0.01m : 1m)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(string)) { if (field != null && MemberHasTranslateAttribute[field] && value != null) { return(Regex.Replace(value, "@[^@]+@", m => Translate(m.Value.Substring(1, m.Value.Length - 2)), RegexOptions.Compiled)); } return(value); } else if (fieldType == typeof(Color)) { Color color; if (value != null && HSLColor.TryParseRGB(value, out color)) { return(color); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Color[])) { if (value != null) { var parts = value.Split(','); var colors = new Color[parts.Length]; for (var i = 0; i < colors.Length; i++) { if (!HSLColor.TryParseRGB(parts[i], out colors[i])) { return(InvalidValueAction(value, fieldType, fieldName)); } } return(colors); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(HSLColor)) { if (value != null) { Color rgb; if (HSLColor.TryParseRGB(value, out rgb)) { return(new HSLColor(rgb)); } // Allow old HSLColor/ColorRamp formats to be parsed as HSLColor var parts = value.Split(','); if (parts.Length == 3 || parts.Length == 4) { return(new HSLColor( (byte)Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255))); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Hotkey)) { Hotkey res; if (Hotkey.TryParse(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WDist)) { WDist res; if (WDist.TryParse(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WVec)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { WDist rx, ry, rz; if (WDist.TryParse(parts[0], out rx) && WDist.TryParse(parts[1], out ry) && WDist.TryParse(parts[2], out rz)) { return(new WVec(rx, ry, rz)); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WVec[])) { if (value != null) { var parts = value.Split(','); if (parts.Length % 3 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var vecs = new WVec[parts.Length / 3]; for (var i = 0; i < vecs.Length; ++i) { WDist rx, ry, rz; if (WDist.TryParse(parts[3 * i], out rx) && WDist.TryParse(parts[3 * i + 1], out ry) && WDist.TryParse(parts[3 * i + 2], out rz)) { vecs[i] = new WVec(rx, ry, rz); } } return(vecs); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WPos)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { WDist rx, ry, rz; if (WDist.TryParse(parts[0], out rx) && WDist.TryParse(parts[1], out ry) && WDist.TryParse(parts[2], out rz)) { return(new WPos(rx, ry, rz)); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WAngle)) { int res; if (Exts.TryParseIntegerInvariant(value, out res)) { return(new WAngle(res)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WRot)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { int rr, rp, ry; if (Exts.TryParseIntegerInvariant(parts[0], out rr) && Exts.TryParseIntegerInvariant(parts[1], out rp) && Exts.TryParseIntegerInvariant(parts[2], out ry)) { return(new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry))); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CPos)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CPos(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CVec)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CVec(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CVec[])) { if (value != null) { var parts = value.Split(','); if (parts.Length % 2 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var vecs = new CVec[parts.Length / 2]; for (var i = 0; i < vecs.Length; i++) { int rx, ry; if (int.TryParse(parts[2 * i], out rx) && int.TryParse(parts[2 * i + 1], out ry)) { vecs[i] = new CVec(rx, ry); } } return(vecs); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(BooleanExpression)) { if (value != null) { try { return(new BooleanExpression(value)); } catch (InvalidDataException e) { throw new YamlException(e.Message); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(IntegerExpression)) { if (value != null) { try { return(new IntegerExpression(value)); } catch (InvalidDataException e) { throw new YamlException(e.Message); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsEnum) { try { return(Enum.Parse(fieldType, value, true)); } catch (ArgumentException) { return(InvalidValueAction(value, fieldType, fieldName)); } } else if (fieldType == typeof(ImageFormat)) { if (value != null) { switch (value.ToLowerInvariant()) { case "bmp": return(ImageFormat.Bmp); case "gif": return(ImageFormat.Gif); case "jpg": case "jpeg": return(ImageFormat.Jpeg); case "tif": case "tiff": return(ImageFormat.Tiff); default: return(ImageFormat.Png); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(bool)) { return(ParseYesNo(value, fieldType, fieldName)); } else if (fieldType.IsArray && fieldType.GetArrayRank() == 1) { if (value == null) { return(Array.CreateInstance(fieldType.GetElementType(), 0)); } var options = field != null && field.HasAttribute <AllowEmptyEntriesAttribute>() ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries; var parts = value.Split(new char[] { ',' }, options); var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length); for (var i = 0; i < parts.Length; i++) { ret.SetValue(GetValue(fieldName, fieldType.GetElementType(), parts[i].Trim(), field), i); } return(ret); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(HashSet <>)) { var set = Activator.CreateInstance(fieldType); if (value == null) { return(set); } var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var addMethod = fieldType.GetMethod("Add", fieldType.GetGenericArguments()); for (var i = 0; i < parts.Length; i++) { addMethod.Invoke(set, new[] { GetValue(fieldName, fieldType.GetGenericArguments()[0], parts[i].Trim(), field) }); } return(set); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { var dict = Activator.CreateInstance(fieldType); var arguments = fieldType.GetGenericArguments(); var addMethod = fieldType.GetMethod("Add", arguments); foreach (var node in yaml.Nodes) { var key = GetValue(fieldName, arguments[0], node.Key, field); var val = GetValue(fieldName, arguments[1], node.Value, field); addMethod.Invoke(dict, new[] { key, val }); } return(dict); } else if (fieldType == typeof(Size)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Size(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(int2)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new int2(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float2)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float xx = 0; float yy = 0; float res; if (float.TryParse(parts[0].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { xx = res * (parts[0].Contains('%') ? 0.01f : 1f); } if (float.TryParse(parts[1].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { yy = res * (parts[1].Contains('%') ? 0.01f : 1f); } return(new float2(xx, yy)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float3)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float x = 0; float y = 0; float z = 0; float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out x); float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out y); // z component is optional for compatibility with older float2 definitions if (parts.Length > 2) { float.TryParse(parts[2], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out z); } return(new float3(x, y, z)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Rectangle)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Rectangle( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]), Exts.ParseIntegerInvariant(parts[2]), Exts.ParseIntegerInvariant(parts[3]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Bits <>)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var argTypes = new Type[] { typeof(string[]) }; var argValues = new object[] { parts }; return(fieldType.GetConstructor(argTypes).Invoke(argValues)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable <>)) { var innerType = fieldType.GetGenericArguments().First(); var innerValue = GetValue("Nullable<T>", innerType, value, field); return(fieldType.GetConstructor(new[] { innerType }).Invoke(new[] { innerValue })); } else if (fieldType == typeof(DateTime)) { DateTime dt; if (DateTime.TryParseExact(value, "yyyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out dt)) { return(dt); } return(InvalidValueAction(value, fieldType, fieldName)); } else { var conv = TypeDescriptor.GetConverter(fieldType); if (conv.CanConvertFrom(typeof(string))) { try { return(conv.ConvertFromInvariantString(value)); } catch { return(InvalidValueAction(value, fieldType, fieldName)); } } } UnknownFieldAction("[Type] {0}".F(value), fieldType); return(null); }
/// <summary> /// /// </summary> /// <param name="fieldName"></param> /// <param name="fieldType"></param> /// <param name="yaml"></param> /// <param name="field"></param> /// <returns></returns> public static object GetValue(string fieldName, Type fieldType, MiniYaml yaml, MemberInfo field) { var value = yaml.Value; if (value != null) { value = value.Trim(); } if (fieldType == typeof(int)) { int res; if (Exts.TryParseIntegerInvariant(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(ushort)) { ushort res; if (ushort.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(long)) { long res; if (long.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float)) { float res; if (value != null && float.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { return(res * (value.Contains('%') ? 0.01f : 1f)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(decimal)) { decimal res; if (value != null && decimal.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { return(res * (value.Contains('%') ? 0.01m : 1m)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(string)) { if (field != null && MemberHasTranslateAttribute[field] && value != null) { } return(value); } else if (fieldType == typeof(WRot)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { int rr, rp, ry; if (Exts.TryParseIntegerInvariant(parts[0], out rr) && Exts.TryParseIntegerInvariant(parts[1], out rp) && Exts.TryParseIntegerInvariant(parts[2], out ry)) { return(new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry))); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WAngle)) { int res; if (Exts.TryParseIntegerInvariant(value, out res)) { return(new WAngle(res)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WVec)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { WDist rx, ry, rz; if (WDist.TryParse(parts[0], out rx) && WDist.TryParse(parts[1], out ry) && WDist.TryParse(parts[2], out rz)) { return(new WVec(rx, ry, rz)); } } } } else if (fieldType == typeof(WVec[])) { if (value != null) { var parts = value.Split(','); if (parts.Length % 3 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var vecs = new WVec[parts.Length / 3]; for (var i = 0; i < vecs.Length; i++) { WDist rx, ry, rz; if (WDist.TryParse(parts[3 * i], out rx) && WDist.TryParse(parts[3 * i + 1], out ry) && WDist.TryParse(parts[3 * i + 2], out rz)) { vecs[i] = new WVec(rx, ry, rz); } } return(vecs); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WDist)) { WDist res; if (WDist.TryParse(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WPos)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { WDist rx, ry, rz; if (WDist.TryParse(parts[0], out rx) && WDist.TryParse(parts[1], out ry) && WDist.TryParse(parts[2], out rz)) { return(new WPos(rx, ry, rz)); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CPos)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CPos(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CVec)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CVec(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } } else if (fieldType == typeof(CVec[])) { if (value != null) { var parts = value.Split(','); if (parts.Length % 2 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var vecs = new CVec[parts.Length / 2]; for (var i = 0; i < vecs.Length; i++) { int rx, ry; if (int.TryParse(parts[2 * i], out rx) && int.TryParse(parts[2 * i + 1], out ry)) { vecs[i] = new CVec(rx, ry); } } return(vecs); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Int2)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Int2(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsEnum) { try { return(Enum.Parse(fieldType, value, true)); } catch (ArgumentException) { return(InvalidValueAction(value, fieldType, fieldName)); } } else if (fieldType == typeof(Size)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Size(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } } else if (fieldType.IsArray && fieldType.GetArrayRank() == 1) //获取Rank属性,例如,一维数组返回1,二维数组返回2 { if (value == null) { return(Array.CreateInstance(fieldType.GetElementType(), 0)); } var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length); for (var i = 0; i < parts.Length; i++) { ret.SetValue(GetValue(fieldName, fieldType.GetElementType(), parts[i].Trim(), field), i); } return(ret); } else if (fieldType == typeof(Rectangle)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Rectangle( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]), Exts.ParseIntegerInvariant(parts[2]), Exts.ParseIntegerInvariant(parts[3]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(EW.Framework.Point)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new EW.Framework.Point(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } } else if (fieldType == typeof(bool)) { return(ParseYesNo(value, fieldType, fieldName)); } else if (fieldType == typeof(Vector2)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float xx = 0; float yy = 0; float res; if (float.TryParse(parts[0].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { xx = res * (parts[0].Contains('%') ? 0.01f : 1f); } if (float.TryParse(parts[1].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { yy = res * (parts[1].Contains('%') ? 0.01f : 1f); } return(new Vector2(xx, yy)); } } else if (fieldType == typeof(Vector3)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float x, y, z = 0; float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out x); float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out y); if (parts.Length > 2) { float.TryParse(parts[2], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out z); } return(new Vector3(x, y, z)); } } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(HashSet <>)) { var set = Activator.CreateInstance(fieldType); if (value == null) { return(set); } var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var addMethod = fieldType.GetMethod("Add", fieldType.GetGenericArguments()); for (var i = 0; i < parts.Length; i++) { addMethod.Invoke(set, new[] { GetValue(fieldName, fieldType.GetGenericArguments()[0], parts[i].Trim(), field) }); } return(set); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { var dict = Activator.CreateInstance(fieldType); var arguments = fieldType.GetGenericArguments(); var addMethod = fieldType.GetMethod("Add", arguments); foreach (var node in yaml.Nodes) { var key = GetValue(fieldName, arguments[0], node.Key, field); var val = GetValue(fieldName, arguments[1], node.Value, field); addMethod.Invoke(dict, new[] { key, val }); } return(dict); } else if (fieldType == typeof(System.Drawing.Color)) { System.Drawing.Color color; if (value != null && HSLColor.TryParseRGB(value, out color)) { return(color); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(System.Drawing.Color[])) { if (value != null) { var parts = value.Split(','); var colors = new System.Drawing.Color[parts.Length]; for (var i = 0; i < parts.Length; i++) { if (!HSLColor.TryParseRGB(parts[i], out colors[i])) { return(InvalidValueAction(value, fieldType, fieldName)); } } return(colors); } } else if (fieldType == typeof(HSLColor)) { if (value != null) { System.Drawing.Color rgb; if (HSLColor.TryParseRGB(value, out rgb)) { return(new HSLColor(rgb)); } //Allowed old HSLColor / ColorRamp formats to be parsed as HSLColor var parts = value.Split(','); if (parts.Length == 3 || parts.Length == 4) { return(new HSLColor((byte)Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255))); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(BooleanExpression)) { if (value != null) { try { return(new BooleanExpression(value)); } catch (InvalidDataException e) { throw new YamlException(e.Message); } } return(InvalidValueAction(value, fieldType, fieldName)); } else { var conv = TypeDescriptor.GetConverter(fieldType); if (conv.CanConvertFrom(typeof(string))) { try { return(conv.ConvertFromInvariantString(value)); } catch { return(InvalidValueAction(value, fieldType, fieldName)); } } } UnknownFieldAction("[Type]{0}".F(value), fieldType); return(null); }