From 6644b1edb823069fa4e0e3b2e66c69c191c298ac Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Sat, 5 Nov 2022 20:27:23 +0100 Subject: [PATCH] some work --- .../Configuration/PluginConfiguration.cs | 5 - .../GameInterface/Nameplates/Nameplate.cs | 127 ++---------------- .../Nameplates/PlayerNameplateUpdatedArgs.cs | 45 +++++-- 3 files changed, 44 insertions(+), 133 deletions(-) diff --git a/PlayerTags/Configuration/PluginConfiguration.cs b/PlayerTags/Configuration/PluginConfiguration.cs index 7c66f13..3c5761b 100644 --- a/PlayerTags/Configuration/PluginConfiguration.cs +++ b/PlayerTags/Configuration/PluginConfiguration.cs @@ -15,11 +15,6 @@ namespace PlayerTags.Configuration public int Version { get; set; } = 0; public bool IsVisible = false; - private const NameplateFreeCompanyVisibility DefaultNameplateFreeCompanyVisibility = Data.NameplateFreeCompanyVisibility.Default; - private const NameplateTitleVisibility DefaultNameplateTitleVisibility = Data.NameplateTitleVisibility.WhenHasTags; - private const NameplateTitlePosition DefaultNameplateTitlePosition = Data.NameplateTitlePosition.AlwaysAboveName; - private const bool DefaultIsApplyTagsToAllChatMessagesEnabled = true; - [Obsolete] [JsonProperty("GeneralOptions")] private Dictionary GeneralOptionsV1 diff --git a/PlayerTags/GameInterface/Nameplates/Nameplate.cs b/PlayerTags/GameInterface/Nameplates/Nameplate.cs index f2bbb38..62c5350 100644 --- a/PlayerTags/GameInterface/Nameplates/Nameplate.cs +++ b/PlayerTags/GameInterface/Nameplates/Nameplate.cs @@ -4,7 +4,9 @@ using Dalamud.Hooking; using Dalamud.Logging; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.UI; +using Pilz.Dalamud.Nameplates; using System; +using System.Diagnostics.Tracing; using System.Linq; using System.Runtime.InteropServices; @@ -15,9 +17,7 @@ namespace PlayerTags.GameInterface.Nameplates /// public class Nameplate : IDisposable { - [Signature("48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 54 41 56 41 57 48 83 EC 40 44 0F B6 E2", DetourName = nameof(SetPlayerNameplateDetour))] - private readonly Hook? hook_AddonNamePlate_SetPlayerNameplateDetour = null; - private unsafe delegate IntPtr AddonNamePlate_SetPlayerNameplateDetour(IntPtr playerNameplateObjectPtr, bool isTitleAboveName, bool isTitleVisible, IntPtr titlePtr, IntPtr namePtr, IntPtr freeCompanyPtr, int iconId); + public NameplateManager NameplateManager { get; init; } /// /// Occurs when a player nameplate is updated by the game. @@ -29,140 +29,37 @@ namespace PlayerTags.GameInterface.Nameplates /// public bool IsValid { - get - { - return hook_AddonNamePlate_SetPlayerNameplateDetour != null - && hook_AddonNamePlate_SetPlayerNameplateDetour.IsEnabled; - } + get => NameplateManager != null && NameplateManager.IsValid; } public Nameplate() { - SignatureHelper.Initialise(this); - hook_AddonNamePlate_SetPlayerNameplateDetour?.Enable(); + NameplateManager = new(); + NameplateManager.Hooks.AddonNamePlate_SetPlayerNameManaged += Hooks_AddonNamePlate_SetPlayerNameManaged; } public void Dispose() { - hook_AddonNamePlate_SetPlayerNameplateDetour?.Disable(); + NameplateManager.Hooks.AddonNamePlate_SetPlayerNameManaged -= Hooks_AddonNamePlate_SetPlayerNameManaged; + NameplateManager.Dispose(); } - private IntPtr SetPlayerNameplateDetour(IntPtr playerNameplateObjectPtr, bool isTitleAboveName, bool isTitleVisible, IntPtr titlePtr, IntPtr namePtr, IntPtr freeCompanyPtr, int iconId) + private void Hooks_AddonNamePlate_SetPlayerNameManaged(Pilz.Dalamud.Nameplates.EventArgs.AddonNamePlate_SetPlayerNameManagedEventArgs eventArgs) { - if (hook_AddonNamePlate_SetPlayerNameplateDetour == null) - { - return IntPtr.Zero; - } - try { - PlayerCharacter? playerCharacter = GetNameplateGameObject(playerNameplateObjectPtr); + PlayerCharacter? playerCharacter = NameplateManager.GetNameplateGameObject(eventArgs.SafeNameplateObject); + if (playerCharacter != null) { - PlayerNameplateUpdatedArgs playerNameplateUpdatedArgs = new PlayerNameplateUpdatedArgs( - playerCharacter, - GameInterfaceHelper.ReadSeString(namePtr), - GameInterfaceHelper.ReadSeString(titlePtr), - GameInterfaceHelper.ReadSeString(freeCompanyPtr), - isTitleVisible, - isTitleAboveName, - iconId); - - byte[] beforeNameBytes = playerNameplateUpdatedArgs.Name.Encode(); - byte[] beforeTitleBytes = playerNameplateUpdatedArgs.Title.Encode(); - byte[] beforeFreeCompanyBytes = playerNameplateUpdatedArgs.FreeCompany.Encode(); - + var playerNameplateUpdatedArgs = new PlayerNameplateUpdatedArgs(playerCharacter, eventArgs); PlayerNameplateUpdated?.Invoke(playerNameplateUpdatedArgs); - - byte[] afterNameBytes = playerNameplateUpdatedArgs.Name.Encode(); - byte[] afterTitleBytes = playerNameplateUpdatedArgs.Title.Encode(); - byte[] afterFreeCompanyBytes = playerNameplateUpdatedArgs.FreeCompany.Encode(); - - IntPtr newNamePtr = namePtr; - bool hasNameChanged = !beforeNameBytes.SequenceEqual(afterNameBytes); - if (hasNameChanged) - { - newNamePtr = GameInterfaceHelper.PluginAllocate(afterNameBytes); - } - - IntPtr newTitlePtr = titlePtr; - bool hasTitleChanged = !beforeTitleBytes.SequenceEqual(afterTitleBytes); - if (hasTitleChanged) - { - newTitlePtr = GameInterfaceHelper.PluginAllocate(afterTitleBytes); - } - - IntPtr newFreeCompanyPtr = freeCompanyPtr; - bool hasFreeCompanyChanged = !beforeFreeCompanyBytes.SequenceEqual(afterFreeCompanyBytes); - if (hasFreeCompanyChanged) - { - newFreeCompanyPtr = GameInterfaceHelper.PluginAllocate(afterFreeCompanyBytes); - } - - var result = hook_AddonNamePlate_SetPlayerNameplateDetour.Original(playerNameplateObjectPtr, playerNameplateUpdatedArgs.IsTitleAboveName, playerNameplateUpdatedArgs.IsTitleVisible, newTitlePtr, newNamePtr, newFreeCompanyPtr, playerNameplateUpdatedArgs.IconId); - - if (hasNameChanged) - { - GameInterfaceHelper.PluginFree(ref newNamePtr); - } - - if (hasTitleChanged) - { - GameInterfaceHelper.PluginFree(ref newTitlePtr); - } - - if (hasFreeCompanyChanged) - { - GameInterfaceHelper.PluginFree(ref newFreeCompanyPtr); - } - - return result; } } catch (Exception ex) { PluginLog.Error(ex, $"SetPlayerNameplateDetour"); } - - return hook_AddonNamePlate_SetPlayerNameplateDetour.Original(playerNameplateObjectPtr, isTitleAboveName, isTitleVisible, titlePtr, namePtr, freeCompanyPtr, iconId); - } - - private T? GetNameplateGameObject(IntPtr nameplateObjectPtr) - where T : GameObject - { - // Get the nameplate object array - var nameplateAddonPtr = PluginServices.GameGui.GetAddonByName("NamePlate", 1); - var nameplateObjectArrayPtrPtr = nameplateAddonPtr + Marshal.OffsetOf(typeof(AddonNamePlate), nameof(AddonNamePlate.NamePlateObjectArray)).ToInt32(); - var nameplateObjectArrayPtr = Marshal.ReadIntPtr(nameplateObjectArrayPtrPtr); - if (nameplateObjectArrayPtr == IntPtr.Zero) - { - return null; - } - - // Determine the index of the nameplate object within the nameplate object array - var namePlateObjectSize = Marshal.SizeOf(typeof(AddonNamePlate.NamePlateObject)); - var namePlateObjectPtr0 = nameplateObjectArrayPtr + namePlateObjectSize * 0; - var namePlateIndex = (nameplateObjectPtr.ToInt64() - namePlateObjectPtr0.ToInt64()) / namePlateObjectSize; - if (namePlateIndex < 0 || namePlateIndex >= AddonNamePlate.NumNamePlateObjects) - { - return null; - } - - // Get the nameplate info array - IntPtr nameplateInfoArrayPtr = IntPtr.Zero; - unsafe - { - var framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance(); - nameplateInfoArrayPtr = new IntPtr(&framework->GetUiModule()->GetRaptureAtkModule()->NamePlateInfoArray); - } - - // Get the nameplate info for the nameplate object - var namePlateInfoPtr = new IntPtr(nameplateInfoArrayPtr.ToInt64() + Marshal.SizeOf(typeof(RaptureAtkModule.NamePlateInfo)) * namePlateIndex); - RaptureAtkModule.NamePlateInfo namePlateInfo = Marshal.PtrToStructure(namePlateInfoPtr); - - // Return the object for its object id - var objectId = namePlateInfo.ObjectID.ObjectID; - return PluginServices.ObjectTable.SearchById(objectId) as T; } } } diff --git a/PlayerTags/GameInterface/Nameplates/PlayerNameplateUpdatedArgs.cs b/PlayerTags/GameInterface/Nameplates/PlayerNameplateUpdatedArgs.cs index 517410a..8621f90 100644 --- a/PlayerTags/GameInterface/Nameplates/PlayerNameplateUpdatedArgs.cs +++ b/PlayerTags/GameInterface/Nameplates/PlayerNameplateUpdatedArgs.cs @@ -1,33 +1,52 @@ using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.Text.SeStringHandling; +using Pilz.Dalamud.Nameplates.EventArgs; namespace PlayerTags.GameInterface.Nameplates { public class PlayerNameplateUpdatedArgs { + private readonly AddonNamePlate_SetPlayerNameManagedEventArgs eventArgs; + public PlayerCharacter PlayerCharacter { get; } - public SeString Name { get; } + public SeString Name + { + get => eventArgs.Name; + } - public SeString Title { get; } + public SeString Title + { + get => eventArgs.Title; + } - public SeString FreeCompany { get; } + public SeString FreeCompany + { + get => eventArgs.FreeCompany; + } - public bool IsTitleVisible { get; set; } + public bool IsTitleVisible + { + get => eventArgs.IsTitleVisible; + set => eventArgs.IsTitleVisible = value; + } - public bool IsTitleAboveName { get; set; } + public bool IsTitleAboveName + { + get => eventArgs.IsTitleAboveName; + set => eventArgs.IsTitleAboveName = value; + } - public int IconId { get; set; } + public int IconId + { + get => eventArgs.IconID; + set => eventArgs.IconID = value; + } - public PlayerNameplateUpdatedArgs(PlayerCharacter playerCharacter, SeString name, SeString title, SeString freeCompany, bool isTitleVisible, bool isTitleAboveName, int iconId) + public PlayerNameplateUpdatedArgs(PlayerCharacter playerCharacter, AddonNamePlate_SetPlayerNameManagedEventArgs eventArgs) { PlayerCharacter = playerCharacter; - Name = name; - Title = title; - FreeCompany = freeCompany; - IsTitleVisible = isTitleVisible; - IsTitleAboveName = isTitleAboveName; - IconId = iconId; + this.eventArgs = eventArgs; } } }