From 57c9e5a731b5c1919cccb307430a508e8f9a4eb4 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 10 Sep 2018 12:06:39 +0300 Subject: [PATCH] Fixed IndexOutOfRange exceptions when cloning items with requiredItems that aren't present in the xml, + some more exception handling & error logging --- Barotrauma/BarotraumaShared/Source/Items/Item.cs | 14 ++++++++++++-- .../BarotraumaShared/Source/Map/MapEntity.cs | 14 +++++++++++++- .../BarotraumaShared/Source/Map/Submarine.cs | 2 +- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 17dd9133d..54ef20b8d 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -495,14 +495,24 @@ namespace Barotrauma if (!property.Value.Attributes.OfType().Any()) continue; clone.properties[property.Key].TrySetValue(property.Value.GetValue()); } - for (int i = 0; i < components.Count; i++) + + if (components.Count != clone.components.Count) + { + string errorMsg = "Error while cloning item \"" + Name + "\" - clone does not have the same number of components. "; + errorMsg += "Original components: " + string.Join(", ", components.Select(c => c.GetType().ToString())); + errorMsg += ", cloned components: " + string.Join(", ", clone.components.Select(c => c.GetType().ToString())); + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce("Item.Clone:" + Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + } + + for (int i = 0; i < components.Count && i < clone.components.Count; i++) { foreach (KeyValuePair property in components[i].properties) { if (!property.Value.Attributes.OfType().Any()) continue; clone.components[i].properties[property.Key].TrySetValue(property.Value.GetValue()); } - for (int j = 0; j < components[i].requiredItems.Count; j++) + for (int j = 0; j < components[i].requiredItems.Count && i < clone.components[i].requiredItems.Count; j++) { clone.components[i].requiredItems[j].JoinedNames = components[i].requiredItems[j].JoinedNames; } diff --git a/Barotrauma/BarotraumaShared/Source/Map/MapEntity.cs b/Barotrauma/BarotraumaShared/Source/Map/MapEntity.cs index 7ca8efdc1..a3dc6f4af 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/MapEntity.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/MapEntity.cs @@ -171,7 +171,19 @@ namespace Barotrauma foreach (MapEntity e in entitiesToClone) { Debug.Assert(e != null); - clones.Add(e.Clone()); + try + { + clones.Add(e.Clone()); + } + catch (Exception ex) + { + DebugConsole.ThrowError("Cloning entity \"" + e.Name + "\" failed.", ex); + GameAnalyticsManager.AddErrorEventOnce( + "MapEntity.Clone:" + e.Name, + GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + "Cloning entity \"" + e.Name + "\" failed (" + ex.Message + ").\n" + ex.StackTrace); + return clones; + } Debug.Assert(clones.Last() != null); } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 9aa51ee67..3b20ba24f 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -170,7 +170,7 @@ namespace Barotrauma { get { - return subBody.Borders; + return subBody == null ? Rectangle.Empty : subBody.Borders; } }