From 410b97823ab610fbf5a036a1f9ea930882922c9f Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Wed, 26 Aug 2015 20:04:51 +0100 Subject: [PATCH 1/3] Ensure our array handling only accepts single dimensional arrays. --- OpenRA.Game/FieldLoader.cs | 2 +- OpenRA.Game/FieldSaver.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/FieldLoader.cs b/OpenRA.Game/FieldLoader.cs index 52273e288a..d93089c1aa 100644 --- a/OpenRA.Game/FieldLoader.cs +++ b/OpenRA.Game/FieldLoader.cs @@ -417,7 +417,7 @@ namespace OpenRA } else if (fieldType == typeof(bool)) return ParseYesNo(value, fieldType, fieldName); - else if (fieldType.IsArray) + else if (fieldType.IsArray && fieldType.GetArrayRank() == 1) { if (value == null) return Array.CreateInstance(fieldType.GetElementType(), 0); diff --git a/OpenRA.Game/FieldSaver.cs b/OpenRA.Game/FieldSaver.cs index 68642475e2..b1facbbe36 100644 --- a/OpenRA.Game/FieldSaver.cs +++ b/OpenRA.Game/FieldSaver.cs @@ -89,7 +89,7 @@ namespace OpenRA return "{0},{1},{2},{3}".F(r.X, r.Y, r.Width, r.Height); } - if (t.IsArray) + if (t.IsArray && t.GetArrayRank() == 1) { var elems = ((Array)v).OfType(); return elems.JoinWith(", "); From 5a177a889c607267b0799d5231600fa26c10bb5a Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Wed, 26 Aug 2015 20:05:29 +0100 Subject: [PATCH 2/3] Add ability to load and save HashSets. --- OpenRA.Game/FieldLoader.cs | 12 ++++++++++++ OpenRA.Game/FieldSaver.cs | 8 ++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/FieldLoader.cs b/OpenRA.Game/FieldLoader.cs index d93089c1aa..66c868730e 100644 --- a/OpenRA.Game/FieldLoader.cs +++ b/OpenRA.Game/FieldLoader.cs @@ -429,6 +429,18 @@ namespace OpenRA 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 == typeof(Size)) { if (value != null) diff --git a/OpenRA.Game/FieldSaver.cs b/OpenRA.Game/FieldSaver.cs index b1facbbe36..70b17ca936 100644 --- a/OpenRA.Game/FieldSaver.cs +++ b/OpenRA.Game/FieldSaver.cs @@ -91,8 +91,12 @@ namespace OpenRA if (t.IsArray && t.GetArrayRank() == 1) { - var elems = ((Array)v).OfType(); - return elems.JoinWith(", "); + return ((Array)v).Cast().JoinWith(", "); + } + + if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(HashSet<>)) + { + return ((System.Collections.IEnumerable)v).Cast().JoinWith(", "); } if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(OpenRA.Primitives.Cache<,>)) From 2f9ca36506c8d1933f8dafee2ea2785d41c4f103 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Thu, 27 Aug 2015 19:14:30 +0100 Subject: [PATCH 3/3] Update WeaponInfo to use HashSets for some fields directly. --- OpenRA.Game/GameRules/WeaponInfo.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 3e5da809e0..aacdb0fea9 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -47,10 +47,10 @@ namespace OpenRA.GameRules public readonly bool Charges = false; [Desc("What types of targets are affected.")] - public readonly string[] ValidTargets = { "Ground", "Water" }; + public readonly HashSet ValidTargets = new HashSet { "Ground", "Water" }; [Desc("What types of targets are unaffected.", "Overrules ValidTargets.")] - public readonly string[] InvalidTargets = { }; + public readonly HashSet InvalidTargets = new HashSet(); [Desc("Delay in ticks between firing shots from the same ammo magazine.")] public readonly int BurstDelay = 5; @@ -64,14 +64,9 @@ namespace OpenRA.GameRules [FieldLoader.LoadUsing("LoadWarheads")] public readonly List Warheads = new List(); - readonly HashSet validTargetSet; - readonly HashSet invalidTargetSet; - public WeaponInfo(string name, MiniYaml content) { FieldLoader.Load(this, content); - validTargetSet = new HashSet(ValidTargets); - invalidTargetSet = new HashSet(InvalidTargets); } static object LoadProjectile(MiniYaml yaml) @@ -99,7 +94,7 @@ namespace OpenRA.GameRules public bool IsValidTarget(IEnumerable targetTypes) { - return validTargetSet.Overlaps(targetTypes) && !invalidTargetSet.Overlaps(targetTypes); + return ValidTargets.Overlaps(targetTypes) && !InvalidTargets.Overlaps(targetTypes); } /// Checks if the weapon is valid against (can target) the target.