diff --git a/MareSynchronos/Managers/CachedPlayer.cs b/MareSynchronos/Managers/CachedPlayer.cs index bb008ff..115374d 100644 --- a/MareSynchronos/Managers/CachedPlayer.cs +++ b/MareSynchronos/Managers/CachedPlayer.cs @@ -454,13 +454,13 @@ public class CachedPlayer : MediatorSubscriberBase, IDisposable if (objectKind == ObjectKind.Player) { - Logger.Debug($"Restoring Customization for {PlayerCharacter}: {_originalGlamourerData}"); + Logger.Debug($"Restoring Customization for {OnlineUser.User.AliasOrUID}/{PlayerName}: {_originalGlamourerData}"); _ipcManager.GlamourerApplyOnlyCustomization(_originalGlamourerData, PlayerCharacter); - Logger.Debug($"Restoring Equipment for {PlayerCharacter}: {_lastGlamourerData}"); + Logger.Debug($"Restoring Equipment for {OnlineUser.User.AliasOrUID}/{PlayerName}: {_lastGlamourerData}"); _ipcManager.GlamourerApplyOnlyEquipment(_lastGlamourerData, PlayerCharacter); - Logger.Debug("Restoring Heels"); + Logger.Debug($"Restoring Heels for {OnlineUser.User.AliasOrUID}/{PlayerName}"); _ipcManager.HeelsRestoreOffsetForPlayer(PlayerCharacter); - Logger.Debug("Restoring C+"); + Logger.Debug($"Restoring C+ for {OnlineUser.User.AliasOrUID}/{PlayerName}"); _ipcManager.CustomizePlusRevert(PlayerCharacter); _ipcManager.PalettePlusRemovePalette(PlayerCharacter); } diff --git a/MareSynchronos/Managers/IpcManager.cs b/MareSynchronos/Managers/IpcManager.cs index cb64c18..c8d186e 100644 --- a/MareSynchronos/Managers/IpcManager.cs +++ b/MareSynchronos/Managers/IpcManager.cs @@ -140,7 +140,7 @@ public class IpcManager : MediatorSubscriberBase, IDisposable _dalamudUtil = dalamudUtil; Mediator.Subscribe(this, (_) => HandleActionQueue()); - Mediator.Subscribe(this, (_) => HandleGposeActionQueue()); + Mediator.Subscribe(this, (_) => HandleGposeActionQueue()); Mediator.Subscribe(this, (_) => ClearActionQueue()); Mediator.Subscribe(this, (_) => PeriodicApiStateCheck()); } diff --git a/MareSynchronos/MareSynchronos.csproj b/MareSynchronos/MareSynchronos.csproj index ba834f5..35d778d 100644 --- a/MareSynchronos/MareSynchronos.csproj +++ b/MareSynchronos/MareSynchronos.csproj @@ -3,7 +3,7 @@ - 0.7.27 + 0.7.28 https://github.com/Penumbra-Sync/client diff --git a/MareSynchronos/Mediator/Messages.cs b/MareSynchronos/Mediator/Messages.cs index 8c7ddbc..0d9f125 100644 --- a/MareSynchronos/Mediator/Messages.cs +++ b/MareSynchronos/Mediator/Messages.cs @@ -14,9 +14,11 @@ public record ClassJobChangedMessage : IMessage; public record DelayedFrameworkUpdateMessage : IMessage; public record ZoneSwitchStartMessage : IMessage; public record ZoneSwitchEndMessage : IMessage; +public record CutsceneStartMessage : IMessage; public record GposeStartMessage : IMessage; public record GposeEndMessage : IMessage; -public record GposeFrameworkUpdateMessage : IMessage; +public record CutsceneEndMessage : IMessage; +public record CutsceneFrameworkUpdateMessage : IMessage; public record ConnectedMessage : IMessage; public record DisconnectedMessage : IMessage; public record PenumbraModSettingChangedMessage : IMessage; diff --git a/MareSynchronos/Models/GameObjectHandler.cs b/MareSynchronos/Models/GameObjectHandler.cs index 8b2daa3..606ea71 100644 --- a/MareSynchronos/Models/GameObjectHandler.cs +++ b/MareSynchronos/Models/GameObjectHandler.cs @@ -56,43 +56,59 @@ public class GameObjectHandler : MediatorSubscriberBase }); } - Mediator.Subscribe(this, (_) => + Mediator.Subscribe(this, (_) => FrameworkUpdate()); + + Mediator.Subscribe(this, (_) => ZoneSwitchEnd()); + Mediator.Subscribe(this, (_) => ZoneSwitchStart()); + + Mediator.Subscribe(this, (_) => { - if (_delayedZoningTask?.IsCompleted ?? true) + Mediator.Unsubscribe(this); + Mediator.Unsubscribe(this); + }); + Mediator.Subscribe(this, (_) => + { + Mediator.Subscribe(this, (_) => ZoneSwitchStart()); + Mediator.Subscribe(this, (_) => FrameworkUpdate()); + }); + } + + private void FrameworkUpdate() + { + if (_delayedZoningTask?.IsCompleted ?? true) + { + CheckAndUpdateObject(); + } + } + + private void ZoneSwitchEnd() + { + if (!_sendUpdates) return; + + _clearCts?.Cancel(); + _clearCts?.Dispose(); + _clearCts = null; + _zoningCts.CancelAfter(2500); + } + + private void ZoneSwitchStart() + { + if (!_sendUpdates) return; + + _zoningCts = new(); + Logger.Debug("Starting Delay After Zoning for " + ObjectKind + " " + Name); + _delayedZoningTask = Task.Run(async () => + { + try { - CheckAndUpdateObject(); + await Task.Delay(TimeSpan.FromSeconds(120), _zoningCts.Token).ConfigureAwait(false); } - }); - - Mediator.Subscribe(this, (_) => - { - if (!watchedObject) return; - - _clearCts?.Cancel(); - _clearCts?.Dispose(); - _clearCts = null; - _zoningCts.CancelAfter(2500); - }); - - Mediator.Subscribe(this, (_) => - { - if (!watchedObject) return; - - _zoningCts = new(); - Logger.Debug("Starting Delay After Zoning for " + ObjectKind + " " + Name); - _delayedZoningTask = Task.Run(async () => + catch { } + finally { - try - { - await Task.Delay(TimeSpan.FromSeconds(120), _zoningCts.Token).ConfigureAwait(false); - } - catch { } - finally - { - Logger.Debug("Delay complete for " + ObjectKind); - _zoningCts.Dispose(); - } - }); + Logger.Debug("Delay complete for " + ObjectKind); + _zoningCts.Dispose(); + } }); } diff --git a/MareSynchronos/UI/CompactUI.cs b/MareSynchronos/UI/CompactUI.cs index 4c6487d..4f3b03a 100644 --- a/MareSynchronos/UI/CompactUI.cs +++ b/MareSynchronos/UI/CompactUI.cs @@ -86,8 +86,8 @@ public class CompactUi : WindowMediatorSubscriberBase, IDisposable Mediator.Subscribe(this, (_) => IsOpen = true); Mediator.Subscribe(this, (_) => IsOpen = false); - Mediator.Subscribe(this, (_) => UiShared_GposeStart()); - Mediator.Subscribe(this, (_) => UiShared_GposeEnd()); + Mediator.Subscribe(this, (_) => UiShared_GposeStart()); + Mediator.Subscribe(this, (_) => UiShared_GposeEnd()); SizeConstraints = new WindowSizeConstraints() { diff --git a/MareSynchronos/UI/SettingsUi.cs b/MareSynchronos/UI/SettingsUi.cs index 0645c4d..b266ccd 100644 --- a/MareSynchronos/UI/SettingsUi.cs +++ b/MareSynchronos/UI/SettingsUi.cs @@ -56,8 +56,8 @@ public class SettingsUi : WindowMediatorSubscriberBase, IDisposable Mediator.Subscribe(this, (_) => Toggle()); Mediator.Subscribe(this, (_) => IsOpen = false); - Mediator.Subscribe(this, (_) => UiShared_GposeStart()); - Mediator.Subscribe(this, (_) => UiShared_GposeEnd()); + Mediator.Subscribe(this, (_) => UiShared_GposeStart()); + Mediator.Subscribe(this, (_) => UiShared_GposeEnd()); Mediator.Subscribe(this, (msg) => LastCreatedCharacterData = ((CharacterDataCreatedMessage)msg).CharacterData.ToAPI()); windowSystem.AddWindow(this); diff --git a/MareSynchronos/UI/UIShared.cs b/MareSynchronos/UI/UIShared.cs index ccc5a99..2f01ac6 100644 --- a/MareSynchronos/UI/UIShared.cs +++ b/MareSynchronos/UI/UIShared.cs @@ -45,7 +45,7 @@ public partial class UiShared : MediatorSubscriberBase public bool EditTrackerPosition { get; set; } public ImFontPtr UidFont { get; private set; } public bool UidFontBuilt { get; private set; } - public bool IsInGpose => _dalamudUtil.IsInGpose; + public bool IsInGpose => _dalamudUtil.IsInCutscene; public static bool CtrlPressed() => (GetKeyState(0xA2) & 0x8000) != 0 || (GetKeyState(0xA3) & 0x8000) != 0; public static bool ShiftPressed() => (GetKeyState(0xA1) & 0x8000) != 0 || (GetKeyState(0xA0) & 0x8000) != 0; diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index 2b0eecf..02079d6 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -16,12 +16,13 @@ public class DalamudUtil : IDisposable private readonly ClientState _clientState; private readonly ObjectTable _objectTable; private readonly Framework _framework; - private readonly Dalamud.Game.ClientState.Conditions.Condition _condition; + private readonly Condition _condition; private readonly MareMediator _mediator; private uint? _classJobId = 0; private DateTime _delayedFrameworkUpdateCheck = DateTime.Now; private bool _sentBetweenAreas = false; + public bool IsInCutscene { get; private set; } = false; public bool IsInGpose { get; private set; } = false; public unsafe bool IsGameObjectPresent(IntPtr key) @@ -38,8 +39,7 @@ public class DalamudUtil : IDisposable } public DalamudUtil(ClientState clientState, ObjectTable objectTable, Framework framework, - Dalamud.Game.ClientState.Conditions.Condition condition, - Dalamud.Data.DataManager gameData, MareMediator mediator) + Condition condition, Dalamud.Data.DataManager gameData, MareMediator mediator) { _clientState = clientState; _objectTable = objectTable; @@ -76,7 +76,25 @@ public class DalamudUtil : IDisposable _mediator.Publish(new GposeEndMessage()); } - if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51] || IsInGpose) + if (_condition[ConditionFlag.WatchingCutscene] && !IsInCutscene) + { + Logger.Debug("Cutscene start"); + IsInCutscene = true; + _mediator.Publish(new CutsceneStartMessage()); + _mediator.Publish(new HaltScanMessage("Cutscene")); + + } + else if (!_condition[ConditionFlag.WatchingCutscene] && IsInCutscene) + { + Logger.Debug("Cutscene end"); + IsInCutscene = false; + _mediator.Publish(new CutsceneEndMessage()); + _mediator.Publish(new ResumeScanMessage("Cutscene")); + } + + if (IsInCutscene) { _mediator.Publish(new CutsceneFrameworkUpdateMessage()); return; } + + if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51]) { if (!_sentBetweenAreas) { @@ -86,8 +104,6 @@ public class DalamudUtil : IDisposable _mediator.Publish(new HaltScanMessage("Zone switch")); } - if (IsInGpose) _mediator.Publish(new GposeFrameworkUpdateMessage()); - return; } @@ -234,16 +250,21 @@ public class DalamudUtil : IDisposable try { // ReSharper disable once LoopVariableIsNeverChangedInsideLoop - while ((!ct?.IsCancellationRequested ?? true) - && curWaitTime < timeOut - && (((obj->GetDrawObject() == null + var stillDrawing = _framework.RunOnFrameworkThread(() => ((obj->GetDrawObject() == null || ((CharacterBase*)obj->GetDrawObject())->HasModelInSlotLoaded != 0 || ((CharacterBase*)obj->GetDrawObject())->HasModelFilesInSlotLoaded != 0)) - || ((obj->RenderFlags & 0b100000000000) == 0b100000000000))) // 0b100000000000 is "still rendering" or something + || ((obj->RenderFlags & 0b100000000000) == 0b100000000000)).Result; + while ((!ct?.IsCancellationRequested ?? true) + && curWaitTime < timeOut + && stillDrawing) // 0b100000000000 is "still rendering" or something { Logger.Verbose($"Waiting for {name} to finish drawing"); curWaitTime += tick; Thread.Sleep(tick); + stillDrawing = _framework.RunOnFrameworkThread(() => ((obj->GetDrawObject() == null + || ((CharacterBase*)obj->GetDrawObject())->HasModelInSlotLoaded != 0 + || ((CharacterBase*)obj->GetDrawObject())->HasModelFilesInSlotLoaded != 0)) + || ((obj->RenderFlags & 0b100000000000) == 0b100000000000)).Result; } } catch (NullReferenceException ex) @@ -256,12 +277,6 @@ public class DalamudUtil : IDisposable } } - public unsafe void DisableDraw(IntPtr characterAddress) - { - var obj = (GameObject*)characterAddress; - obj->DisableDraw(); - } - public unsafe void WaitWhileGposeCharacterIsDrawing(IntPtr characterAddress, int timeOut = 5000) { Thread.Sleep(500);