From 7391be7e56fb2bf71095920c4ac736047c9f2c07 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 29 Mar 2020 13:40:31 -0700 Subject: [PATCH] Add origin updating for villager imports --- NHSE.Core/Save/Files/Personal.cs | 2 +- .../Structures/Villager/IVillagerOrigin.cs | 39 +++++++++++++++++++ NHSE.Core/Structures/Villager/Villager.cs | 5 ++- NHSE.WinForms/Editor.cs | 19 +++++++-- 4 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 NHSE.Core/Structures/Villager/IVillagerOrigin.cs diff --git a/NHSE.Core/Save/Files/Personal.cs b/NHSE.Core/Save/Files/Personal.cs index bc6e00a..235e9dd 100644 --- a/NHSE.Core/Save/Files/Personal.cs +++ b/NHSE.Core/Save/Files/Personal.cs @@ -6,7 +6,7 @@ namespace NHSE.Core /// /// personal.dat /// - public sealed class Personal : EncryptedFilePair + public sealed class Personal : EncryptedFilePair, IVillagerOrigin { public readonly PersonalOffsets Offsets; public Personal(string folder) : base(folder, "personal") => Offsets = PersonalOffsets.GetOffsets(Info); diff --git a/NHSE.Core/Structures/Villager/IVillagerOrigin.cs b/NHSE.Core/Structures/Villager/IVillagerOrigin.cs new file mode 100644 index 0000000..21ac045 --- /dev/null +++ b/NHSE.Core/Structures/Villager/IVillagerOrigin.cs @@ -0,0 +1,39 @@ +using System.Linq; + +namespace NHSE.Core +{ + public interface IVillagerOrigin + { + byte[] GetTownIdentity(); + byte[] GetPlayerIdentity(); + } + + public static class VillagerOriginExtensions + { + public static bool IsOriginatedFrom(this IVillagerOrigin visit, IVillagerOrigin host) + { + var hostTown = host.GetTownIdentity(); + var visitTown = visit.GetTownIdentity(); + if (!hostTown.SequenceEqual(visitTown)) + return false; + + var hostPlayer = host.GetTownIdentity(); + var visitPlayer = visit.GetTownIdentity(); + if (!hostPlayer.SequenceEqual(visitPlayer)) + return false; + + return true; + } + + public static void ChangeOrigins(this IVillagerOrigin visit, IVillagerOrigin host, byte[] visitData) + { + var hostTown = host.GetTownIdentity(); + var visitTown = visit.GetTownIdentity(); + visitData.ReplaceOccurrences(visitTown, hostTown); + + var hostPlayer = host.GetTownIdentity(); + var visitPlayer = visit.GetTownIdentity(); + visitData.ReplaceOccurrences(visitPlayer, hostPlayer); + } + } +} \ No newline at end of file diff --git a/NHSE.Core/Structures/Villager/Villager.cs b/NHSE.Core/Structures/Villager/Villager.cs index b22a8ab..ed85ae4 100644 --- a/NHSE.Core/Structures/Villager/Villager.cs +++ b/NHSE.Core/Structures/Villager/Villager.cs @@ -3,7 +3,7 @@ namespace NHSE.Core { - public class Villager + public class Villager : IVillagerOrigin { public readonly byte[] Data; public Villager(byte[] data) => Data = data; @@ -37,6 +37,7 @@ public string TownName get => GetString(0x08, 10); set => GetBytes(value, 10).CopyTo(Data, 0x08); } + public byte[] GetTownIdentity() => Data.Slice(0x04, 4 + 20); public uint PlayerID { @@ -50,6 +51,8 @@ public string PlayerName set => GetBytes(value, 10).CopyTo(Data, 0x24); } + public byte[] GetPlayerIdentity() => Data.Slice(0x20, 4 + 20); + public string TownName2 { get => GetString(0x5CC, 10); diff --git a/NHSE.WinForms/Editor.cs b/NHSE.WinForms/Editor.cs index aa3fe98..5c539df 100644 --- a/NHSE.WinForms/Editor.cs +++ b/NHSE.WinForms/Editor.cs @@ -326,8 +326,8 @@ private void B_LoadVillager_Click(object sender, EventArgs e) return; var file = ofd.FileName; - var v = SAV.Main.GetVillager(VillagerIndex); - var expectLength = v.Data.Length; + var original = SAV.Main.GetVillager(VillagerIndex); + var expectLength = original.Data.Length; var fi = new FileInfo(file); if (fi.Length != expectLength) { @@ -336,8 +336,19 @@ private void B_LoadVillager_Click(object sender, EventArgs e) return; } - var update = File.ReadAllBytes(ofd.FileName); - update.CopyTo(v.Data, 0); + var data = File.ReadAllBytes(ofd.FileName); + var v = new Villager(data); + var player0 = SAV.Players[0].Personal; + if (!v.IsOriginatedFrom(player0)) + { + var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, + $"Imported Villager did not originate from Villager0 ({player0.PlayerName})'s data.", "Update values?"); + if (result == DialogResult.Cancel) + return; + if (result == DialogResult.Yes) + v.ChangeOrigins(player0, v.Data); + } + SAV.Main.SetVillager(v, VillagerIndex); } }