some updates
This commit is contained in:
@@ -11,8 +11,8 @@ namespace Pilz.Dalamud.ActivityContexts
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum ActivityType
|
||||
{
|
||||
None,
|
||||
PveDuty,
|
||||
PvpDuty
|
||||
None = 0x0,
|
||||
PveDuty = 0x1,
|
||||
PvpDuty = 0x2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@ namespace Pilz.Dalamud.Nameplates.EventArgs
|
||||
{
|
||||
public class AddonNamePlate_SetPlayerNameManagedEventArgs : HookWithResultManagedBaseEventArgs<IntPtr>
|
||||
{
|
||||
private new AddonNamePlate_SetPlayerNameEventArgs OriginalEventArgs
|
||||
=> base.OriginalEventArgs as AddonNamePlate_SetPlayerNameEventArgs;
|
||||
public new AddonNamePlate_SetPlayerNameEventArgs OriginalEventArgs
|
||||
{
|
||||
get => base.OriginalEventArgs as AddonNamePlate_SetPlayerNameEventArgs;
|
||||
set => base.OriginalEventArgs = value;
|
||||
}
|
||||
|
||||
public SafeNameplateObject SafeNameplateObject { get; set; }
|
||||
public SeString Title { get; set; }
|
||||
|
||||
@@ -8,6 +8,11 @@ namespace Pilz.Dalamud.Nameplates.EventArgs
|
||||
{
|
||||
public abstract class HookBaseEventArgs
|
||||
{
|
||||
public bool CallOriginal { get; set; } = true;
|
||||
internal event Action CallOriginal;
|
||||
|
||||
public void Original()
|
||||
{
|
||||
CallOriginal?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,16 @@ using System.Threading.Tasks;
|
||||
|
||||
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; }
|
||||
|
||||
// Call Original based on the given properties
|
||||
public TResult Original()
|
||||
{
|
||||
return CallOriginal.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ namespace Pilz.Dalamud.Nameplates.Model
|
||||
{
|
||||
public class SafeNameplateObject
|
||||
{
|
||||
public readonly IntPtr Pointer;
|
||||
public readonly AddonNamePlate.NamePlateObject Data;
|
||||
public IntPtr Pointer { get; }
|
||||
public AddonNamePlate.NamePlateObject Data { get; }
|
||||
|
||||
private int _Index;
|
||||
private SafeNameplateInfo _NamePlateInfo;
|
||||
|
||||
@@ -8,6 +8,8 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Pilz.Dalamud.Nameplates.Model;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using System.Xml.Linq;
|
||||
|
||||
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.
|
||||
/// </summary>
|
||||
public event AddonNamePlate_SetPlayerNameEventHandler AddonNamePlate_SetPlayerName;
|
||||
public delegate IntPtr AddonNamePlate_SetPlayerNameEventHandler(AddonNamePlate_SetPlayerNameEventArgs eventArgs);
|
||||
public delegate void AddonNamePlate_SetPlayerNameEventHandler(AddonNamePlate_SetPlayerNameEventArgs eventArgs);
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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))]
|
||||
private readonly Hook<AddonNamePlate_SetPlayerNameplateDetour>? hook_AddonNamePlate_SetPlayerNameplateDetour = null;
|
||||
@@ -91,10 +93,6 @@ namespace Pilz.Dalamud.Nameplates
|
||||
|
||||
if (IsHookEnabled(hook_AddonNamePlate_SetPlayerNameplateDetour))
|
||||
{
|
||||
var freeTitle = false;
|
||||
var freeName = false;
|
||||
var freeFreeCompany = false;
|
||||
|
||||
var eventArgs = new AddonNamePlate_SetPlayerNameEventArgs
|
||||
{
|
||||
PlayerNameplateObjectPtr = playerNameplateObjectPtr,
|
||||
@@ -106,11 +104,34 @@ namespace Pilz.Dalamud.Nameplates
|
||||
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
|
||||
var hasDefaultHookEvent = AddonNamePlate_SetPlayerName != null;
|
||||
AddonNamePlate_SetPlayerName?.Invoke(eventArgs);
|
||||
|
||||
if (AddonNamePlate_SetPlayerNameManaged != null)
|
||||
{
|
||||
var freeTitle = false;
|
||||
var freeName = false;
|
||||
var freeFreeCompany = false;
|
||||
|
||||
// Create NamePlateObject if possible
|
||||
var namePlateObj = new SafeNameplateObject(playerNameplateObjectPtr);
|
||||
|
||||
@@ -155,28 +176,26 @@ namespace Pilz.Dalamud.Nameplates
|
||||
eventArgs.FreeCompanyPtr = GameInterfaceHelper.PluginAllocate(freeCompanyNewRaw);
|
||||
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
|
||||
if (eventArgs.CallOriginal)
|
||||
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);
|
||||
// Set result
|
||||
result = eventArgs.Result;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
using Dalamud.Hooking;
|
||||
using Pilz.Dalamud.Nameplates.EventArgs;
|
||||
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
|
||||
{
|
||||
@@ -33,5 +37,47 @@ namespace Pilz.Dalamud.Nameplates
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.Plugin;
|
||||
@@ -11,16 +12,13 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Dalamud
|
||||
{
|
||||
internal class PluginServices
|
||||
public class PluginServices
|
||||
{
|
||||
[PluginService]
|
||||
public static GameGui GameGui { get; private set; } = null!;
|
||||
[PluginService]
|
||||
public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
|
||||
[PluginService]
|
||||
public static ClientState ClientState { get; private set; } = null!;
|
||||
[PluginService]
|
||||
public static DataManager DataManager { get; private set; } = null!;
|
||||
[PluginService] public static GameGui GameGui { get; private set; } = null!;
|
||||
[PluginService] public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
|
||||
[PluginService] public static ClientState ClientState { get; private set; } = null!;
|
||||
[PluginService] public static DataManager DataManager { get; private set; } = null!;
|
||||
[PluginService] public static ObjectTable ObjectTable { get; private set; } = null!;
|
||||
|
||||
public static void Initialize(DalamudPluginInterface dalamudPluginInterface)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user