Fix buggy behavior deleting spawned gpose actors

This commit is contained in:
Loporrit
2025-07-25 15:54:12 +00:00
parent 10366695f2
commit 9fd390caab
3 changed files with 26 additions and 23 deletions

View File

@@ -13,9 +13,9 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
private readonly GameObjectHandlerFactory _gameObjectHandlerFactory; private readonly GameObjectHandlerFactory _gameObjectHandlerFactory;
private readonly DalamudUtilService _dalamudUtilService; private readonly DalamudUtilService _dalamudUtilService;
private readonly IpcManager _ipcManager; private readonly IpcManager _ipcManager;
private readonly HashSet<HandledCharaDataEntry> _handledCharaData = []; private readonly Dictionary<string, HandledCharaDataEntry> _handledCharaData = new(StringComparer.Ordinal);
public IEnumerable<HandledCharaDataEntry> HandledCharaData => _handledCharaData; public IReadOnlyDictionary<string, HandledCharaDataEntry> HandledCharaData => _handledCharaData;
public CharaDataCharacterHandler(ILogger<CharaDataCharacterHandler> logger, MareMediator mediator, public CharaDataCharacterHandler(ILogger<CharaDataCharacterHandler> logger, MareMediator mediator,
GameObjectHandlerFactory gameObjectHandlerFactory, DalamudUtilService dalamudUtilService, GameObjectHandlerFactory gameObjectHandlerFactory, DalamudUtilService dalamudUtilService,
@@ -29,7 +29,7 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
{ {
foreach (var chara in _handledCharaData) foreach (var chara in _handledCharaData)
{ {
_ = RevertHandledChara(chara); _ = RevertHandledChara(chara.Value);
} }
}); });
@@ -40,13 +40,13 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
{ {
if (!_dalamudUtilService.IsInGpose) return; if (!_dalamudUtilService.IsInGpose) return;
foreach (var entry in _handledCharaData.ToList()) foreach (var entry in _handledCharaData.Values.ToList())
{ {
var chara = _dalamudUtilService.GetGposeCharacterFromObjectTableByName(entry.Name, onlyGposeCharacters: true); var chara = _dalamudUtilService.GetGposeCharacterFromObjectTableByName(entry.Name, onlyGposeCharacters: true);
if (chara is null) if (chara is null)
{ {
RevertChara(entry.Name, entry.CustomizePlus).GetAwaiter().GetResult(); _handledCharaData.Remove(entry.Name);
_handledCharaData.Remove(entry); _ = _dalamudUtilService.RunOnFrameworkThread(() => RevertChara(entry.Name, entry.CustomizePlus));
} }
} }
} }
@@ -54,12 +54,17 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
base.Dispose(disposing); base.Dispose(disposing);
foreach (var chara in _handledCharaData) foreach (var chara in _handledCharaData.Values)
{ {
_ = RevertHandledChara(chara); _ = RevertHandledChara(chara);
} }
} }
public HandledCharaDataEntry? GetHandledCharacter(string name)
{
return _handledCharaData.GetValueOrDefault(name);
}
public async Task RevertChara(string name, Guid? cPlusId) public async Task RevertChara(string name, Guid? cPlusId)
{ {
Guid applicationId = Guid.NewGuid(); Guid applicationId = Guid.NewGuid();
@@ -77,28 +82,26 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
public async Task<bool> RevertHandledChara(string name) public async Task<bool> RevertHandledChara(string name)
{ {
var handled = _handledCharaData.FirstOrDefault(f => string.Equals(f.Name, name, StringComparison.Ordinal)); var handled = _handledCharaData.GetValueOrDefault(name);
return await RevertHandledChara(handled).ConfigureAwait(false);
}
public async Task<bool> RevertHandledChara(HandledCharaDataEntry? handled)
{
if (handled == null) return false; if (handled == null) return false;
_handledCharaData.Remove(handled); _handledCharaData.Remove(handled.Name);
await _dalamudUtilService.RunOnFrameworkThread(() => RevertChara(handled.Name, handled.CustomizePlus)).ConfigureAwait(false); await _dalamudUtilService.RunOnFrameworkThread(() => RevertChara(handled.Name, handled.CustomizePlus)).ConfigureAwait(false);
return true; return true;
} }
public Task RevertHandledChara(HandledCharaDataEntry? handled)
{
if (handled == null) return Task.CompletedTask;
_handledCharaData.Remove(handled);
return _dalamudUtilService.RunOnFrameworkThread(() => RevertChara(handled.Name, handled.CustomizePlus));
}
internal void AddHandledChara(HandledCharaDataEntry handledCharaDataEntry) internal void AddHandledChara(HandledCharaDataEntry handledCharaDataEntry)
{ {
_handledCharaData.Add(handledCharaDataEntry); _handledCharaData.Add(handledCharaDataEntry.Name, handledCharaDataEntry);
} }
public void UpdateHandledData(Dictionary<string, CharaDataMetaInfoExtendedDto?> newData) public void UpdateHandledData(Dictionary<string, CharaDataMetaInfoExtendedDto?> newData)
{ {
foreach (var handledData in _handledCharaData) foreach (var handledData in _handledCharaData.Values)
{ {
if (newData.TryGetValue(handledData.MetaInfo.FullId, out var metaInfo) && metaInfo != null) if (newData.TryGetValue(handledData.MetaInfo.FullId, out var metaInfo) && metaInfo != null)
{ {

View File

@@ -93,7 +93,7 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase
public Task<List<CharaDataFullExtendedDto>>? GetAllDataTask { get; private set; } public Task<List<CharaDataFullExtendedDto>>? GetAllDataTask { get; private set; }
public Task<List<CharaDataMetaInfoDto>>? GetSharedWithYouTask { get; private set; } public Task<List<CharaDataMetaInfoDto>>? GetSharedWithYouTask { get; private set; }
public Task? GetSharedWithYouTimeoutTask { get; private set; } public Task? GetSharedWithYouTimeoutTask { get; private set; }
public IEnumerable<HandledCharaDataEntry> HandledCharaData => _characterHandler.HandledCharaData; public IReadOnlyDictionary<string, HandledCharaDataEntry> HandledCharaData => _characterHandler.HandledCharaData;
public bool Initialized { get; private set; } public bool Initialized { get; private set; }
public CharaDataMetaInfoExtendedDto? LastDownloadedMetaInfo { get; private set; } public CharaDataMetaInfoExtendedDto? LastDownloadedMetaInfo { get; private set; }
public Task<(MareCharaFileHeader LoadedFile, long ExpectedLength)>? LoadedMcdfHeader { get; private set; } public Task<(MareCharaFileHeader LoadedFile, long ExpectedLength)>? LoadedMcdfHeader { get; private set; }
@@ -546,7 +546,7 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase
await ApplyCharaData(charaDataDownloadDto, newActor.Name.TextValue).ConfigureAwait(false); await ApplyCharaData(charaDataDownloadDto, newActor.Name.TextValue).ConfigureAwait(false);
return _characterHandler.HandledCharaData.FirstOrDefault(f => string.Equals(f.Name, newActor.Name.TextValue, StringComparison.Ordinal)); return _characterHandler.HandledCharaData.GetValueOrDefault(newActor.Name.TextValue);
}); });
UiBlockingComputation = task; UiBlockingComputation = task;
return task; return task;
@@ -562,7 +562,7 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase
await ApplyCharaData(charaDataMetaInfoDto, newActor.Name.TextValue).ConfigureAwait(false); await ApplyCharaData(charaDataMetaInfoDto, newActor.Name.TextValue).ConfigureAwait(false);
return _characterHandler.HandledCharaData.FirstOrDefault(f => string.Equals(f.Name, newActor.Name.TextValue, StringComparison.Ordinal)); return _characterHandler.HandledCharaData.GetValueOrDefault(newActor.Name.TextValue);
}); });
UiBlockingComputation = task; UiBlockingComputation = task;
return task; return task;

View File

@@ -203,7 +203,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
using var tabs = ImRaii.TabBar("TabsTopLevel"); using var tabs = ImRaii.TabBar("TabsTopLevel");
bool smallUi = false; bool smallUi = false;
_isHandlingSelf = _charaDataManager.HandledCharaData.Any(c => c.IsSelf); _isHandlingSelf = _charaDataManager.HandledCharaData.Any(c => c.Value.IsSelf);
if (_isHandlingSelf) _openMcdOnlineOnNextRun = false; if (_isHandlingSelf) _openMcdOnlineOnNextRun = false;
using (var gposeTogetherTabItem = ImRaii.TabItem("GPose Together")) using (var gposeTogetherTabItem = ImRaii.TabItem("GPose Together"))
@@ -388,7 +388,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
ImGui.TextUnformatted(CharaName(actor.Name.TextValue)); ImGui.TextUnformatted(CharaName(actor.Name.TextValue));
} }
ImGui.SameLine(250); ImGui.SameLine(250);
var handled = _charaDataManager.HandledCharaData.FirstOrDefault(c => string.Equals(c.Name, actor.Name.TextValue, StringComparison.Ordinal)); var handled = _charaDataManager.HandledCharaData.GetValueOrDefault(actor.Name.TextValue);
using (ImRaii.Disabled(handled == null)) using (ImRaii.Disabled(handled == null))
{ {
_uiSharedService.IconText(FontAwesomeIcon.InfoCircle); _uiSharedService.IconText(FontAwesomeIcon.InfoCircle);