From b0ec5297f42518eca228b1c8346ec78573181b1e Mon Sep 17 00:00:00 2001 From: Nazfib Date: Tue, 18 Jun 2024 17:50:45 +0200 Subject: [PATCH] Fix an IndexOutOfRangeException in DragCube.Load() The name field in a DRAG_CUBE config node is supposed to be optional. However, when the name is not included in the list of values, an IndexOutOfRangeException is thrown. Even when not loaded from a config file, when the name field on a DragCube object is the empty string (for example, when it is default-constructed in code) it is not included in the string returned by DragCube.SaveToString(); this causes a problem when the FlightIntegrator.Setup() method uses this string to create a clone of a drag cube. The first instructions in DragCube.Load(string[] data) are: - Check if it has the correct length (24 or 25), logging an error and returning if this is not the case - Check if the length is 12; if it is not, take the first field as the name and skip it. That last check should have been against a length of 24 instead; this patch replaces the first occurrence of ldc.i4.s 12 in the code by ldc.i4.s 24. I've checked KSP version 1.0.5 (the oldest version available via Steam), and the bug was already present in that version; the code seems to be unchanged between then and version 1.12.5. --- GameData/KSPCommunityFixes/Settings.cfg | 3 ++ .../BugFixes/DragCubeLoadException.cs | 49 +++++++++++++++++++ KSPCommunityFixes/KSPCommunityFixes.csproj | 1 + README.md | 1 + 4 files changed, 54 insertions(+) create mode 100644 KSPCommunityFixes/BugFixes/DragCubeLoadException.cs diff --git a/GameData/KSPCommunityFixes/Settings.cfg b/GameData/KSPCommunityFixes/Settings.cfg index d5ceb7d1..9ce767ed 100644 --- a/GameData/KSPCommunityFixes/Settings.cfg +++ b/GameData/KSPCommunityFixes/Settings.cfg @@ -222,6 +222,9 @@ KSP_COMMUNITY_FIXES // cargo bays, wrong vessel size being reported, etc... PartBoundsIgnoreDisabledTransforms = true + // Fix loading of drag cubes without a name failing with an IndexOutOfRangeException + DragCubeLoadException = true + // ########################## // Obsolete bugfixes // ########################## diff --git a/KSPCommunityFixes/BugFixes/DragCubeLoadException.cs b/KSPCommunityFixes/BugFixes/DragCubeLoadException.cs new file mode 100644 index 00000000..12d4c02d --- /dev/null +++ b/KSPCommunityFixes/BugFixes/DragCubeLoadException.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Reflection.Emit; +using HarmonyLib; + +namespace KSPCommunityFixes.BugFixes +{ +class DragCubeLoadException : BasePatch +{ + // The name field in a DRAG_CUBE config node is supposed to be optional. However, when the name is not included in + // the list of values, an IndexOutOfRangeException is thrown. + // + // Even when not loaded from a config file, when the name field on a DragCube object is the empty string (for + // example, when it is default-constructed in code) it is not included in the string returned by + // DragCube.SaveToString(); this causes a problem when the FlightIntegrator.Setup() method uses this string to + // create a clone of a drag cube. + + protected override Version VersionMin => new Version(1, 8, 0); + + protected override void ApplyPatches(List patches) + { + patches.Add( + new PatchInfo( + PatchMethodType.Transpiler, + AccessTools.Method(typeof(DragCube), nameof(DragCube.Load)), + this)); + } + + static IEnumerable DragCube_Load_Transpiler(IEnumerable instructions) + { + // The first instructions in DragCube.Load(string[] data) are: + // - Check if it has the correct length (24 or 25), logging an error and returning if this is not the case + // - Check if the length is 12; if it is not, take the first field as the name and skip it. + // That last check should have been against a length of 24 instead; this patch replaces the first occurrence of + // ldc.i4.s 12 in the code by ldc.i4.s 24. + + bool found = false; + foreach (var instruction in instructions) + { + if (!found && instruction.Is(OpCodes.Ldc_I4_S, (sbyte)12)) + { + found = true; + instruction.operand = (sbyte)24; + } + yield return instruction; + } + } +} +} diff --git a/KSPCommunityFixes/KSPCommunityFixes.csproj b/KSPCommunityFixes/KSPCommunityFixes.csproj index 5ccec49f..1d962f8f 100644 --- a/KSPCommunityFixes/KSPCommunityFixes.csproj +++ b/KSPCommunityFixes/KSPCommunityFixes.csproj @@ -104,6 +104,7 @@ + diff --git a/README.md b/README.md index f6d141d9..5d5de081 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ User options are available from the "ESC" in-game settings menu :