From db54e5ae1c2412d3e20405da29017fa43fa71f1f Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 17 Jan 2026 16:14:09 -0600 Subject: [PATCH] Fix identity swap when using span slices Closes #684 Defensively allocate a copy so that the replacement does not overwrite the original sequence A=>B then continue doing B=>B swaps. Wasn't a problem before since properties fetched byte[] (allocated separate slice); changing to span introduced this regression -- now fixed. --- NHSE.Core/Save/Meta/HorizonSave.cs | 1 + NHSE.Core/Structures/Villager/IVillagerOrigin.cs | 4 ++-- NHSE.WinForms/Editor.cs | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/NHSE.Core/Save/Meta/HorizonSave.cs b/NHSE.Core/Save/Meta/HorizonSave.cs index 526d488..1719c88 100644 --- a/NHSE.Core/Save/Meta/HorizonSave.cs +++ b/NHSE.Core/Save/Meta/HorizonSave.cs @@ -77,6 +77,7 @@ public IEnumerable GetInvalidHashes() public void ChangeIdentity(ReadOnlySpan original, ReadOnlySpan updated) { + original = original.ToArray(); // defensive allocation to ensure the sequence stays the same during replacement Main.Data.ReplaceOccurrences(original, updated); foreach (var pair in Players.SelectMany(z => z)) pair.Data.ReplaceOccurrences(original, updated); diff --git a/NHSE.Core/Structures/Villager/IVillagerOrigin.cs b/NHSE.Core/Structures/Villager/IVillagerOrigin.cs index cc1a67e..15c182c 100644 --- a/NHSE.Core/Structures/Villager/IVillagerOrigin.cs +++ b/NHSE.Core/Structures/Villager/IVillagerOrigin.cs @@ -40,14 +40,14 @@ public static void ChangeOrigins(this IVillagerOrigin visit, IVillagerOrigin hos private static void ChangeToHostTown(this IVillagerOrigin visit, IVillagerOrigin host, Span visitData) { var hostTown = host.GetTownIdentity(); - var visitTown = visit.GetTownIdentity(); + var visitTown = visit.GetTownIdentity().ToArray(); visitData.ReplaceOccurrences(visitTown, hostTown); } private static void ChangeToHostPlayer(this IVillagerOrigin visit, IVillagerOrigin host, Span visitData) { var hostPlayer = host.GetPlayerIdentity(); - var visitPlayer = visit.GetPlayerIdentity(); + var visitPlayer = visit.GetPlayerIdentity().ToArray(); visitData.ReplaceOccurrences(visitPlayer, hostPlayer); } } \ No newline at end of file diff --git a/NHSE.WinForms/Editor.cs b/NHSE.WinForms/Editor.cs index 54a8574..8734ca4 100644 --- a/NHSE.WinForms/Editor.cs +++ b/NHSE.WinForms/Editor.cs @@ -346,14 +346,14 @@ private void SavePlayer(int index) if (pers.PlayerName != TB_Name.Text) { - var orig = pers.GetPlayerIdentity(); + var orig = pers.GetPlayerIdentity().ToArray(); pers.PlayerName = TB_Name.Text; var updated = pers.GetPlayerIdentity(); SAV.ChangeIdentity(orig, updated); } if (pers.TownName != TB_TownName.Text) { - var orig = pers.GetTownIdentity(); + var orig = pers.GetTownIdentity().ToArray(); pers.TownName = TB_TownName.Text; var updated = pers.GetTownIdentity(); SAV.ChangeIdentity(orig, updated);