diff --git a/ARControl/AutoRetainerControlPlugin.Sync.cs b/ARControl/AutoRetainerControlPlugin.Sync.cs index c271035..59a7107 100644 --- a/ARControl/AutoRetainerControlPlugin.Sync.cs +++ b/ARControl/AutoRetainerControlPlugin.Sync.cs @@ -44,14 +44,43 @@ partial class AutoRetainerControlPlugin save = true; } - List seenRetainers = new(); + // migrate legacy retainers + foreach (var legacyRetainer in character.Retainers.Where(x => x.RetainerContentId == 0)) + { + var retainerData = + offlineCharacterData.RetainerData.SingleOrDefault(x => legacyRetainer.Name == x.Name); + if (retainerData != null) + { + _pluginLog.Information( + $"Assigning contentId {retainerData.RetainerID} to retainer {retainerData.Name}"); + legacyRetainer.RetainerContentId = retainerData.RetainerID; + save = true; + } + } + + var retainersWithoutContentId = character.Retainers.Where(c => c.RetainerContentId == 0).ToList(); + if (retainersWithoutContentId.Count > 0) + { + foreach (var retainer in retainersWithoutContentId) + { + _pluginLog.Warning($"Removing retainer {retainer.Name} without contentId"); + character.Retainers.Remove(retainer); + } + + save = true; + } + + List unknownRetainerIds = offlineCharacterData.RetainerData.Select(x => x.RetainerID).Where(x => x != 0).ToList(); foreach (var retainerData in offlineCharacterData.RetainerData) { - var retainer = character.Retainers.SingleOrDefault(x => x.Name == retainerData.Name); + unknownRetainerIds.Remove(retainerData.RetainerID); + + var retainer = character.Retainers.SingleOrDefault(x => x.RetainerContentId == retainerData.RetainerID); if (retainer == null) { retainer = new Configuration.RetainerConfiguration { + RetainerContentId = retainerData.RetainerID, Name = retainerData.Name, Managed = false, }; @@ -60,7 +89,11 @@ partial class AutoRetainerControlPlugin character.Retainers.Add(retainer); } - seenRetainers.Add(retainer.Name); + if (retainer.Name != retainerData.Name) + { + retainer.Name = retainerData.Name; + save = true; + } if (retainer.DisplayOrder != retainerData.DisplayOrder) { @@ -113,8 +146,16 @@ partial class AutoRetainerControlPlugin } } - if (character.Retainers.RemoveAll(x => !seenRetainers.Contains(x.Name)) > 0) + if (unknownRetainerIds.Count > 0) + { + foreach (var retainerId in unknownRetainerIds) + { + _pluginLog.Warning($"Removing unknown retainer with contentId {retainerId}"); + character.Retainers.RemoveAll(c => c.RetainerContentId == retainerId); + } + save = true; + } } if (save) diff --git a/ARControl/AutoRetainerControlPlugin.cs b/ARControl/AutoRetainerControlPlugin.cs index 9702d47..d227acf 100644 --- a/ARControl/AutoRetainerControlPlugin.cs +++ b/ARControl/AutoRetainerControlPlugin.cs @@ -374,7 +374,10 @@ public sealed partial class AutoRetainerControlPlugin : IDalamudPlugin if (s.Length > 1) retainerName = ch.Retainers.SingleOrDefault(x => x.Name.EqualsIgnoreCase(s[1]))?.Name; else - retainerName = ch.Retainers.MinBy(x => x.DisplayOrder)?.Name; + retainerName = ch.Retainers + .OrderBy(x => x.DisplayOrder) + .ThenBy(x => x.RetainerContentId) + .FirstOrDefault()?.Name; if (retainerName == null) { diff --git a/ARControl/Configuration.cs b/ARControl/Configuration.cs index 264fd04..cb7137f 100644 --- a/ARControl/Configuration.cs +++ b/ARControl/Configuration.cs @@ -97,6 +97,7 @@ internal sealed class Configuration : IPluginConfiguration public sealed class RetainerConfiguration { + public ulong RetainerContentId { get; set; } public required string Name { get; set; } public required bool Managed { get; set; } public int DisplayOrder { get; set; } diff --git a/ARControl/Windows/ConfigWindow.cs b/ARControl/Windows/ConfigWindow.cs index b13568f..402cdfc 100644 --- a/ARControl/Windows/ConfigWindow.cs +++ b/ARControl/Windows/ConfigWindow.cs @@ -635,7 +635,8 @@ internal sealed class ConfigWindow : LImGui.LWindow if (ImGui.BeginTabItem("Retainers")) { foreach (var retainer in character.Retainers.Where(x => x.Job > 0) - .OrderBy(x => x.DisplayOrder)) + .OrderBy(x => x.DisplayOrder) + .ThenBy(x => x.RetainerContentId)) { ImGui.BeginDisabled(retainer.Level < MinLevel); @@ -649,7 +650,7 @@ internal sealed class ConfigWindow : LImGui.LWindow } if (ImGui.Checkbox( - $"{retainer.Name}###Retainer{retainer.Name}{retainer.DisplayOrder}", + $"{retainer.Name}###Retainer{retainer.Name}{retainer.RetainerContentId}", ref managed)) { retainer.Managed = managed; diff --git a/AutoRetainerAPI b/AutoRetainerAPI index 7cb5477..7ff1513 160000 --- a/AutoRetainerAPI +++ b/AutoRetainerAPI @@ -1 +1 @@ -Subproject commit 7cb54772e3a4a60ad02520e898d1ed0e82b2a751 +Subproject commit 7ff15133ac0d48e9aa57f69524bd9daf36c609bc