some updates

This commit is contained in:
2022-11-05 20:50:30 +01:00
parent 9a72e2025e
commit fc21145061
8 changed files with 123 additions and 44 deletions

View File

@@ -11,8 +11,8 @@ namespace Pilz.Dalamud.ActivityContexts
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public enum ActivityType public enum ActivityType
{ {
None, None = 0x0,
PveDuty, PveDuty = 0x1,
PvpDuty PvpDuty = 0x2
} }
} }

View File

@@ -10,8 +10,11 @@ namespace Pilz.Dalamud.Nameplates.EventArgs
{ {
public class AddonNamePlate_SetPlayerNameManagedEventArgs : HookWithResultManagedBaseEventArgs<IntPtr> public class AddonNamePlate_SetPlayerNameManagedEventArgs : HookWithResultManagedBaseEventArgs<IntPtr>
{ {
private new AddonNamePlate_SetPlayerNameEventArgs OriginalEventArgs public new AddonNamePlate_SetPlayerNameEventArgs OriginalEventArgs
=> base.OriginalEventArgs as AddonNamePlate_SetPlayerNameEventArgs; {
get => base.OriginalEventArgs as AddonNamePlate_SetPlayerNameEventArgs;
set => base.OriginalEventArgs = value;
}
public SafeNameplateObject SafeNameplateObject { get; set; } public SafeNameplateObject SafeNameplateObject { get; set; }
public SeString Title { get; set; } public SeString Title { get; set; }

View File

@@ -8,6 +8,11 @@ namespace Pilz.Dalamud.Nameplates.EventArgs
{ {
public abstract class HookBaseEventArgs public abstract class HookBaseEventArgs
{ {
public bool CallOriginal { get; set; } = true; internal event Action CallOriginal;
public void Original()
{
CallOriginal?.Invoke();
}
} }
} }

View File

@@ -6,8 +6,16 @@ using System.Threading.Tasks;
namespace Pilz.Dalamud.Nameplates.EventArgs namespace Pilz.Dalamud.Nameplates.EventArgs
{ {
public abstract class HookWithResultBaseEventArgs<TResult> : HookBaseEventArgs public abstract class HookWithResultBaseEventArgs<TResult>
{ {
internal event Func<TResult> CallOriginal;
public TResult Result { get; set; } public TResult Result { get; set; }
// Call Original based on the given properties
public TResult Original()
{
return CallOriginal.Invoke();
}
} }
} }

View File

@@ -12,8 +12,8 @@ namespace Pilz.Dalamud.Nameplates.Model
{ {
public class SafeNameplateObject public class SafeNameplateObject
{ {
public readonly IntPtr Pointer; public IntPtr Pointer { get; }
public readonly AddonNamePlate.NamePlateObject Data; public AddonNamePlate.NamePlateObject Data { get; }
private int _Index; private int _Index;
private SafeNameplateInfo _NamePlateInfo; private SafeNameplateInfo _NamePlateInfo;

View File

@@ -8,6 +8,8 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Pilz.Dalamud.Nameplates.Model; using Pilz.Dalamud.Nameplates.Model;
using Lumina.Excel.GeneratedSheets;
using System.Xml.Linq;
namespace Pilz.Dalamud.Nameplates namespace Pilz.Dalamud.Nameplates
{ {
@@ -17,14 +19,14 @@ namespace Pilz.Dalamud.Nameplates
/// Will be executed when the the Game wants to update the content of a nameplate with the details of the Player. /// Will be executed when the the Game wants to update the content of a nameplate with the details of the Player.
/// </summary> /// </summary>
public event AddonNamePlate_SetPlayerNameEventHandler AddonNamePlate_SetPlayerName; public event AddonNamePlate_SetPlayerNameEventHandler AddonNamePlate_SetPlayerName;
public delegate IntPtr AddonNamePlate_SetPlayerNameEventHandler(AddonNamePlate_SetPlayerNameEventArgs eventArgs); public delegate void AddonNamePlate_SetPlayerNameEventHandler(AddonNamePlate_SetPlayerNameEventArgs eventArgs);
/// <summary> /// <summary>
/// Will be executed when the the Game wants to update the content of a nameplate with the details of the Player. /// Will be executed when the the Game wants to update the content of a nameplate with the details of the Player.
/// This will event acts on a higher level with SeString instead of IntPtr e.g. /// This will event acts on a higher level with SeString instead of IntPtr e.g.
/// </summary> /// </summary>
public event AddonNamePlate_SetPlayerNameManagedEventHandler AddonNamePlate_SetPlayerNameManaged; public event AddonNamePlate_SetPlayerNameManagedEventHandler AddonNamePlate_SetPlayerNameManaged;
public delegate IntPtr AddonNamePlate_SetPlayerNameManagedEventHandler(AddonNamePlate_SetPlayerNameManagedEventArgs eventArgs); public delegate void AddonNamePlate_SetPlayerNameManagedEventHandler(AddonNamePlate_SetPlayerNameManagedEventArgs eventArgs);
[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))] [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<AddonNamePlate_SetPlayerNameplateDetour>? hook_AddonNamePlate_SetPlayerNameplateDetour = null; private readonly Hook<AddonNamePlate_SetPlayerNameplateDetour>? hook_AddonNamePlate_SetPlayerNameplateDetour = null;
@@ -91,10 +93,6 @@ namespace Pilz.Dalamud.Nameplates
if (IsHookEnabled(hook_AddonNamePlate_SetPlayerNameplateDetour)) if (IsHookEnabled(hook_AddonNamePlate_SetPlayerNameplateDetour))
{ {
var freeTitle = false;
var freeName = false;
var freeFreeCompany = false;
var eventArgs = new AddonNamePlate_SetPlayerNameEventArgs var eventArgs = new AddonNamePlate_SetPlayerNameEventArgs
{ {
PlayerNameplateObjectPtr = playerNameplateObjectPtr, PlayerNameplateObjectPtr = playerNameplateObjectPtr,
@@ -106,11 +104,34 @@ namespace Pilz.Dalamud.Nameplates
IconID = iconId IconID = iconId
}; };
void callOriginal()
{
eventArgs.Result = eventArgs.Original();
}
// Add handler for the Original call
eventArgs.CallOriginal += () =>
{
return hook_AddonNamePlate_SetPlayerNameplateDetour.Original(
eventArgs.PlayerNameplateObjectPtr,
eventArgs.IsTitleAboveName,
eventArgs.IsTitleVisible,
eventArgs.TitlePtr,
eventArgs.NamePtr,
eventArgs.FreeCompanyPtr,
eventArgs.IconID);
};
// Invoke Event // Invoke Event
var hasDefaultHookEvent = AddonNamePlate_SetPlayerName != null;
AddonNamePlate_SetPlayerName?.Invoke(eventArgs); AddonNamePlate_SetPlayerName?.Invoke(eventArgs);
if (AddonNamePlate_SetPlayerNameManaged != null) if (AddonNamePlate_SetPlayerNameManaged != null)
{ {
var freeTitle = false;
var freeName = false;
var freeFreeCompany = false;
// Create NamePlateObject if possible // Create NamePlateObject if possible
var namePlateObj = new SafeNameplateObject(playerNameplateObjectPtr); var namePlateObj = new SafeNameplateObject(playerNameplateObjectPtr);
@@ -155,28 +176,26 @@ namespace Pilz.Dalamud.Nameplates
eventArgs.FreeCompanyPtr = GameInterfaceHelper.PluginAllocate(freeCompanyNewRaw); eventArgs.FreeCompanyPtr = GameInterfaceHelper.PluginAllocate(freeCompanyNewRaw);
freeFreeCompany = true; freeFreeCompany = true;
} }
// Call Original as we changed something
callOriginal();
// Free memory
if (freeTitle)
GameInterfaceHelper.PluginFree(eventArgs.TitlePtr);
if (freeName)
GameInterfaceHelper.PluginFree(eventArgs.NamePtr);
if (freeFreeCompany)
GameInterfaceHelper.PluginFree(eventArgs.FreeCompanyPtr);
}
else if(!hasDefaultHookEvent)
{
// Call original in case of nothing get called, just to get secure it will not break the game when not calling it.
callOriginal();
} }
// Call Original and set result // Set result
if (eventArgs.CallOriginal) result = eventArgs.Result;
result = hook_AddonNamePlate_SetPlayerNameplateDetour.Original(
eventArgs.PlayerNameplateObjectPtr,
eventArgs.IsTitleAboveName,
eventArgs.IsTitleVisible,
eventArgs.TitlePtr,
eventArgs.NamePtr,
eventArgs.FreeCompanyPtr,
eventArgs.IconID);
else
result = eventArgs.Result;
// Free memory
if (freeTitle)
GameInterfaceHelper.PluginFree(eventArgs.TitlePtr);
if (freeName)
GameInterfaceHelper.PluginFree(eventArgs.NamePtr);
if (freeFreeCompany)
GameInterfaceHelper.PluginFree(eventArgs.FreeCompanyPtr);
} }
return result; return result;

View File

@@ -1,6 +1,10 @@
using Dalamud.Hooking; using Dalamud.Hooking;
using Pilz.Dalamud.Nameplates.EventArgs; using Pilz.Dalamud.Nameplates.EventArgs;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.UI;
using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Objects.Types;
using Pilz.Dalamud.Nameplates.Model;
namespace Pilz.Dalamud.Nameplates namespace Pilz.Dalamud.Nameplates
{ {
@@ -33,5 +37,47 @@ namespace Pilz.Dalamud.Nameplates
{ {
Hooks?.Dispose(); Hooks?.Dispose();
} }
public static T? GetNameplateGameObject<T>(SafeNameplateObject namePlateObject) where T : GameObject
{
return GetNameplateGameObject<T>(namePlateObject.Pointer);
}
public static T? GetNameplateGameObject<T>(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<RaptureAtkModule.NamePlateInfo>(namePlateInfoPtr);
// Return the object for its object id
var objectId = namePlateInfo.ObjectID.ObjectID;
return PluginServices.ObjectTable.SearchById(objectId) as T;
}
} }
} }

View File

@@ -1,5 +1,6 @@
using Dalamud.Data; using Dalamud.Data;
using Dalamud.Game.ClientState; using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using Dalamud.IoC; using Dalamud.IoC;
using Dalamud.Plugin; using Dalamud.Plugin;
@@ -11,16 +12,13 @@ using System.Threading.Tasks;
namespace Pilz.Dalamud namespace Pilz.Dalamud
{ {
internal class PluginServices public class PluginServices
{ {
[PluginService] [PluginService] public static GameGui GameGui { get; private set; } = null!;
public static GameGui GameGui { get; private set; } = null!; [PluginService] public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService] [PluginService] public static ClientState ClientState { get; private set; } = null!;
public static DalamudPluginInterface PluginInterface { get; private set; } = null!; [PluginService] public static DataManager DataManager { get; private set; } = null!;
[PluginService] [PluginService] public static ObjectTable ObjectTable { get; private set; } = null!;
public static ClientState ClientState { get; private set; } = null!;
[PluginService]
public static DataManager DataManager { get; private set; } = null!;
public static void Initialize(DalamudPluginInterface dalamudPluginInterface) public static void Initialize(DalamudPluginInterface dalamudPluginInterface)
{ {