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))]
public enum ActivityType
{
None,
PveDuty,
PvpDuty
None = 0x0,
PveDuty = 0x1,
PvpDuty = 0x2
}
}

View File

@@ -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; }

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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)
{