From 5cdb9e6dfa680b027b9494d18723e4031287d3fd Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Wed, 24 Aug 2022 22:02:56 +0200 Subject: [PATCH] fix minions/mounts for 6.2, todo: remove penumbra redraw once glamourer is available --- MareAPI | 2 +- .../Factories/CharacterDataFactory.cs | 19 ++++---- MareSynchronos/Managers/CachedPlayer.cs | 46 ++++++++----------- MareSynchronos/Managers/PlayerManager.cs | 5 +- MareSynchronos/MareSynchronos.csproj | 2 +- MareSynchronos/Models/PlayerRelatedObject.cs | 39 ++++++++-------- .../WebAPI/ApiController.Connectivity.cs | 26 +++++++++-- Penumbra | 2 +- 8 files changed, 72 insertions(+), 69 deletions(-) diff --git a/MareAPI b/MareAPI index 374cc31..37d4eb5 160000 --- a/MareAPI +++ b/MareAPI @@ -1 +1 @@ -Subproject commit 374cc31babec9ac37aa21104d7fc02e41cd0d38e +Subproject commit 37d4eb5b1d8fc7d6adba0d58fa3cfdf79542700f diff --git a/MareSynchronos/Factories/CharacterDataFactory.cs b/MareSynchronos/Factories/CharacterDataFactory.cs index ee851d9..5ea8582 100644 --- a/MareSynchronos/Factories/CharacterDataFactory.cs +++ b/MareSynchronos/Factories/CharacterDataFactory.cs @@ -31,14 +31,14 @@ public class CharacterDataFactory _ipcManager = ipcManager; } - public CharacterData BuildCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr playerPointer, CancellationToken token) + public unsafe CharacterData BuildCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr playerPointer, CancellationToken token) { if (!_ipcManager.Initialized) { throw new ArgumentException("Penumbra is not connected"); } - if (playerPointer == IntPtr.Zero) + if (playerPointer == IntPtr.Zero || ((Character*)playerPointer)->GameObject.GetDrawObject() == null) { Logger.Verbose("Pointer was zero for " + objectKind); previousData.FileReplacements.Remove(objectKind); @@ -198,6 +198,11 @@ public class CharacterDataFactory private unsafe CharacterData CreateCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr charaPointer, CancellationToken token) { + if (previousData.FileReplacements.ContainsKey(objectKind)) + { + previousData.FileReplacements[objectKind].Clear(); + } + Stopwatch st = Stopwatch.StartNew(); var chara = _dalamudUtil.CreateGameObject(charaPointer)!; while (!_dalamudUtil.IsObjectPresent(chara)) @@ -207,17 +212,9 @@ public class CharacterDataFactory } _dalamudUtil.WaitWhileCharacterIsDrawing(charaPointer); - if (previousData.FileReplacements.ContainsKey(objectKind)) - { - previousData.FileReplacements[objectKind].Clear(); - } - previousData.ManipulationString = _ipcManager.PenumbraGetMetaManipulations(); - if (objectKind is not ObjectKind.Mount) - { - previousData.GlamourerString[objectKind] = _ipcManager.GlamourerGetCharacterCustomization(chara); - } + previousData.GlamourerString[objectKind] = _ipcManager.GlamourerGetCharacterCustomization(chara); var human = (Human*)((Character*)charaPointer)->GameObject.GetDrawObject(); for (var mdlIdx = 0; mdlIdx < human->CharacterBase.SlotCount; ++mdlIdx) diff --git a/MareSynchronos/Managers/CachedPlayer.cs b/MareSynchronos/Managers/CachedPlayer.cs index 335eb43..a7b62fd 100644 --- a/MareSynchronos/Managers/CachedPlayer.cs +++ b/MareSynchronos/Managers/CachedPlayer.cs @@ -236,14 +236,18 @@ public class CachedPlayer Logger.Debug( $"Request Redraw for {PlayerName}"); _ipcManager.GlamourerApplyAll(glamourerData, PlayerCharacter.Address); + // todo: remove + _ipcManager.PenumbraRedraw(PlayerCharacter.Address); } - else if (objectKind == ObjectKind.Minion) + else if (objectKind == ObjectKind.MinionOrMount) { - var minion = ((Character*)PlayerCharacter.Address)->CompanionObject; - if (minion != null) + var minionOrMount = ((Character*)PlayerCharacter.Address)->CompanionObject; + if (minionOrMount != null) { - Logger.Debug($"Request Redraw for Minion"); - _ipcManager.GlamourerApplyAll(glamourerData, obj: (IntPtr)minion); + Logger.Debug($"Request Redraw for Minion/Mount"); + _ipcManager.GlamourerApplyAll(glamourerData, obj: (IntPtr)minionOrMount); + // todo: remove + _ipcManager.PenumbraRedraw((IntPtr)minionOrMount); } } else if (objectKind == ObjectKind.Pet) @@ -253,6 +257,8 @@ public class CachedPlayer { Logger.Debug("Request Redraw for Pet"); _ipcManager.GlamourerApplyAll(glamourerData, pet); + // todo: remove + _ipcManager.PenumbraRedraw(pet); } } else if (objectKind == ObjectKind.Companion) @@ -262,15 +268,8 @@ public class CachedPlayer { Logger.Debug("Request Redraw for Companion"); _ipcManager.GlamourerApplyAll(glamourerData, companion); - } - } - else if (objectKind == ObjectKind.Mount) - { - var mount = ((CharaExt*)PlayerCharacter.Address)->Mount; - if (mount != null) - { - Logger.Debug($"Request Redraw for Mount"); - _ipcManager.PenumbraRedraw((IntPtr)mount); + // todo: remove + _ipcManager.PenumbraRedraw(companion); } } } @@ -283,13 +282,15 @@ public class CachedPlayer { _ipcManager.GlamourerApplyOnlyCustomization(_originalGlamourerData, PlayerCharacter); _ipcManager.GlamourerApplyOnlyEquipment(_lastGlamourerData, PlayerCharacter); + // todo: remove + _ipcManager.PenumbraRedraw(PlayerCharacter.Address); } - else if (objectKind == ObjectKind.Minion) + else if (objectKind == ObjectKind.MinionOrMount) { - var minion = ((Character*)PlayerCharacter.Address)->CompanionObject; - if (minion != null) + var minionOrMount = ((Character*)PlayerCharacter.Address)->CompanionObject; + if (minionOrMount != null) { - _ipcManager.PenumbraRedraw((IntPtr)minion); + _ipcManager.PenumbraRedraw((IntPtr)minionOrMount); } } else if (objectKind == ObjectKind.Pet) @@ -308,14 +309,6 @@ public class CachedPlayer _ipcManager.PenumbraRedraw(companion); } } - else if (objectKind == ObjectKind.Mount) - { - var mount = ((CharaExt*)PlayerCharacter.Address)->Mount; - if (mount != null) - { - _ipcManager.PenumbraRedraw((IntPtr)mount); - } - } } public void DisposePlayer() @@ -429,6 +422,7 @@ public class CachedPlayer Logger.Debug($"Player {PlayerName} changed, PenumbraRedraw is {RequestedPenumbraRedraw}"); if (!RequestedPenumbraRedraw && PlayerCharacter is not null) { + _currentCharacterEquipment.HasUnprocessedUpdate = false; Logger.Debug($"Saving new Glamourer data"); _lastGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter!); } diff --git a/MareSynchronos/Managers/PlayerManager.cs b/MareSynchronos/Managers/PlayerManager.cs index d23bbed..feca223 100644 --- a/MareSynchronos/Managers/PlayerManager.cs +++ b/MareSynchronos/Managers/PlayerManager.cs @@ -5,12 +5,10 @@ using System; using System.Threading; using System.Threading.Tasks; using MareSynchronos.API; -using Penumbra.GameData.Structs; using FFXIVClientStructs.FFXIV.Client.Game.Character; using System.Collections.Generic; using System.Linq; using MareSynchronos.Models; -using MareSynchronos.Interop; namespace MareSynchronos.Managers { @@ -55,10 +53,9 @@ namespace MareSynchronos.Managers playerRelatedObjects = new List() { new PlayerRelatedObject(ObjectKind.Player, IntPtr.Zero, IntPtr.Zero, () => _dalamudUtil.PlayerPointer), - new PlayerRelatedObject(ObjectKind.Minion, IntPtr.Zero, IntPtr.Zero, () => (IntPtr)((Character*)_dalamudUtil.PlayerPointer)->CompanionObject), + new PlayerRelatedObject(ObjectKind.MinionOrMount, IntPtr.Zero, IntPtr.Zero, () => (IntPtr)((Character*)_dalamudUtil.PlayerPointer)->CompanionObject), new PlayerRelatedObject(ObjectKind.Pet, IntPtr.Zero, IntPtr.Zero, () => _dalamudUtil.GetPet()), new PlayerRelatedObject(ObjectKind.Companion, IntPtr.Zero, IntPtr.Zero, () => _dalamudUtil.GetCompanion()), - new PlayerRelatedObject(ObjectKind.Mount, IntPtr.Zero, IntPtr.Zero, () => (IntPtr)((CharaExt*)_dalamudUtil.PlayerPointer)->Mount), }; } diff --git a/MareSynchronos/MareSynchronos.csproj b/MareSynchronos/MareSynchronos.csproj index 3153f8f..33749dd 100644 --- a/MareSynchronos/MareSynchronos.csproj +++ b/MareSynchronos/MareSynchronos.csproj @@ -21,7 +21,7 @@ - $(appdata)\XIVLauncher\addon\Hooks\6692d56\ + $(appdata)\XIVLauncher\addon\Hooks\Dev\ diff --git a/MareSynchronos/Models/PlayerRelatedObject.cs b/MareSynchronos/Models/PlayerRelatedObject.cs index 08b4393..62096f1 100644 --- a/MareSynchronos/Models/PlayerRelatedObject.cs +++ b/MareSynchronos/Models/PlayerRelatedObject.cs @@ -47,7 +47,7 @@ namespace MareSynchronos.Models var chara = (Character*)curPtr; bool addr = Address == IntPtr.Zero || Address != curPtr; bool equip = CompareAndUpdateByteData(chara->EquipSlotData, chara->CustomizeData); - bool drawObj = (chara->GameObject.DrawObject != null && (IntPtr)chara->GameObject.DrawObject != DrawObjectAddress); + bool drawObj = (IntPtr)chara->GameObject.DrawObject != DrawObjectAddress; var name = new Utf8String(chara->GameObject.Name).ToString(); bool nameChange = (name != _name); if (addr || equip || drawObj || nameChange) @@ -98,33 +98,30 @@ namespace MareSynchronos.Models } } - if (ObjectKind is not ObjectKind.Mount) + var newHatState = Marshal.ReadByte((IntPtr)customizeData + 30, 0); + var newWeaponOrVisorState = Marshal.ReadByte((IntPtr)customizeData + 31, 0); + if (newHatState != HatState) { - var newHatState = Marshal.ReadByte((IntPtr)customizeData + 30, 0); - var newWeaponOrVisorState = Marshal.ReadByte((IntPtr)customizeData + 31, 0); - if (newHatState != HatState) + if (HatState != null && !hasChanges && !HasUnprocessedUpdate) { - if (HatState != null && !hasChanges && !HasUnprocessedUpdate) - { - Logger.Debug("Not Sending Update, only Hat changed"); - DoNotSendUpdate = true; - } - HatState = newHatState; - hasChanges = true; + Logger.Debug("Not Sending Update, only Hat changed"); + DoNotSendUpdate = true; } + HatState = newHatState; + hasChanges = true; + } - newWeaponOrVisorState &= 0b1101; // ignore drawing weapon + newWeaponOrVisorState &= 0b1101; // ignore drawing weapon - if (newWeaponOrVisorState != VisorWeaponState) + if (newWeaponOrVisorState != VisorWeaponState) + { + if (VisorWeaponState != null && !hasChanges && !HasUnprocessedUpdate) { - if (VisorWeaponState != null && !hasChanges && !HasUnprocessedUpdate) - { - Logger.Debug("Not Sending Update, only Visor/Weapon changed"); - DoNotSendUpdate = true; - } - VisorWeaponState = newWeaponOrVisorState; - hasChanges = true; + Logger.Debug("Not Sending Update, only Visor/Weapon changed"); + DoNotSendUpdate = true; } + VisorWeaponState = newWeaponOrVisorState; + hasChanges = true; } return hasChanges; diff --git a/MareSynchronos/WebAPI/ApiController.Connectivity.cs b/MareSynchronos/WebAPI/ApiController.Connectivity.cs index 4df15ba..bb87e34 100644 --- a/MareSynchronos/WebAPI/ApiController.Connectivity.cs +++ b/MareSynchronos/WebAPI/ApiController.Connectivity.cs @@ -124,12 +124,24 @@ namespace MareSynchronos.WebAPI private string ApiUri => _pluginConfiguration.ApiUri; public int OnlineUsers => SystemInfoDto.OnlineUsers; - public ServerState ServerState { get; private set; } + private ServerState _serverState; + public ServerState ServerState + { + get => _serverState; + private set + { + Logger.Debug($"New ServerState: {value}, prev ServerState: {_serverState}"); + _serverState = value; + } + } public async Task CreateConnections() { + await StopConnection(_connectionCancellationTokenSource.Token); + if (_pluginConfiguration.FullPause) { + Logger.Info("Not recreating Connection, paused"); ServerState = ServerState.Disconnected; _connectionDto = null; return; @@ -137,8 +149,6 @@ namespace MareSynchronos.WebAPI Logger.Info("Recreating Connection"); - await StopConnection(_connectionCancellationTokenSource.Token); - _connectionCancellationTokenSource.Cancel(); _connectionCancellationTokenSource = new CancellationTokenSource(); var token = _connectionCancellationTokenSource.Token; @@ -298,9 +308,9 @@ namespace MareSynchronos.WebAPI CurrentUploads.Clear(); CurrentDownloads.Clear(); _uploadCancellationTokenSource?.Cancel(); - Logger.Info("Connection closed"); Disconnected?.Invoke(); ServerState = ServerState.Offline; + Logger.Info("Connection closed"); return Task.CompletedTask; } @@ -337,6 +347,14 @@ namespace MareSynchronos.WebAPI await _mareHub.DisposeAsync(); _mareHub = null; } + + if (ServerState != ServerState.Disconnected) + { + while (ServerState != ServerState.Offline) + { + await Task.Delay(16); + } + } } } } diff --git a/Penumbra b/Penumbra index cfeb20a..e66ca7c 160000 --- a/Penumbra +++ b/Penumbra @@ -1 +1 @@ -Subproject commit cfeb20a18efc41221ca5aaa2f3562c93536a8f4d +Subproject commit e66ca7c5805bf23a82b51649e7f5f75baabe4bc7