Compare commits
2 Commits
e0fff565bd
...
6df71875cc
Author | SHA1 | Date |
---|---|---|
Anna | 6df71875cc | |
Anna | f22702f251 |
|
@ -2,13 +2,15 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
/// The class containing BattleTalk functionality
|
||||
/// </summary>
|
||||
public class BattleTalk : IDisposable {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// The class containing BattleTalk functionality
|
||||
/// </summary>
|
||||
public class BattleTalk : IDisposable {
|
||||
private bool HookEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -31,7 +33,7 @@ namespace XivCommon.Functions {
|
|||
private AddBattleTalkDelegate? AddBattleTalk { get; }
|
||||
private Hook<AddBattleTalkDelegate>? AddBattleTalkHook { get; }
|
||||
|
||||
internal unsafe BattleTalk(bool hook) {
|
||||
internal unsafe BattleTalk(IGameInteropProvider interop, bool hook) {
|
||||
this.HookEnabled = hook;
|
||||
|
||||
var addBattleTalkPtr = (IntPtr) Framework.Instance()->GetUiModule()->VTable->ShowBattleTalk;
|
||||
|
@ -39,7 +41,7 @@ namespace XivCommon.Functions {
|
|||
this.AddBattleTalk = Marshal.GetDelegateForFunctionPointer<AddBattleTalkDelegate>(addBattleTalkPtr);
|
||||
|
||||
if (this.HookEnabled) {
|
||||
this.AddBattleTalkHook = Hook<AddBattleTalkDelegate>.FromAddress(addBattleTalkPtr, this.AddBattleTalkDetour);
|
||||
this.AddBattleTalkHook = interop.HookFromAddress<AddBattleTalkDelegate>(addBattleTalkPtr, this.AddBattleTalkDetour);
|
||||
this.AddBattleTalkHook.Enable();
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +60,7 @@ namespace XivCommon.Functions {
|
|||
try {
|
||||
return this.AddBattleTalkDetourInner(uiModule, senderPtr, messagePtr, duration, style);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in BattleTalk detour");
|
||||
Logger.Log.Error(ex, "Exception in BattleTalk detour");
|
||||
}
|
||||
|
||||
Return:
|
||||
|
@ -81,7 +83,7 @@ namespace XivCommon.Functions {
|
|||
try {
|
||||
this.OnBattleTalk?.Invoke(ref sender, ref message, ref options, ref handled);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in BattleTalk event");
|
||||
Logger.Log.Error(ex, "Exception in BattleTalk event");
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
|
@ -133,12 +135,12 @@ namespace XivCommon.Functions {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Options for displaying a BattleTalk window.
|
||||
/// </summary>
|
||||
public class BattleTalkOptions {
|
||||
/// <summary>
|
||||
/// Options for displaying a BattleTalk window.
|
||||
/// </summary>
|
||||
public class BattleTalkOptions {
|
||||
/// <summary>
|
||||
/// Duration to display the window, in seconds.
|
||||
/// </summary>
|
||||
|
@ -148,12 +150,12 @@ namespace XivCommon.Functions {
|
|||
/// The style of the window.
|
||||
/// </summary>
|
||||
public BattleTalkStyle Style { get; set; } = BattleTalkStyle.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BattleTalk window styles.
|
||||
/// </summary>
|
||||
public enum BattleTalkStyle : byte {
|
||||
/// <summary>
|
||||
/// BattleTalk window styles.
|
||||
/// </summary>
|
||||
public enum BattleTalkStyle : byte {
|
||||
/// <summary>
|
||||
/// A normal battle talk window with a white background.
|
||||
/// </summary>
|
||||
|
@ -178,5 +180,4 @@ namespace XivCommon.Functions {
|
|||
/// </para>
|
||||
/// </summary>
|
||||
Blue = 9,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,12 @@ using FFXIVClientStructs.FFXIV.Client.System.Memory;
|
|||
using FFXIVClientStructs.FFXIV.Client.System.String;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
/// A class containing chat functionality
|
||||
/// </summary>
|
||||
public class Chat {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// A class containing chat functionality
|
||||
/// </summary>
|
||||
public class Chat {
|
||||
private static class Signatures {
|
||||
internal const string SendChat = "48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 45 84 C9";
|
||||
internal const string SanitiseString = "E8 ?? ?? ?? ?? EB 0A 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8D 8D";
|
||||
|
@ -23,7 +24,7 @@ namespace XivCommon.Functions {
|
|||
|
||||
private readonly unsafe delegate* unmanaged<Utf8String*, int, IntPtr, void> _sanitiseString = null!;
|
||||
|
||||
internal Chat(SigScanner scanner) {
|
||||
internal Chat(ISigScanner scanner) {
|
||||
if (scanner.TryScanText(Signatures.SendChat, out var processChatBoxPtr, "chat sending")) {
|
||||
this.ProcessChatBox = Marshal.GetDelegateForFunctionPointer<ProcessChatBoxDelegate>(processChatBoxPtr);
|
||||
}
|
||||
|
@ -153,5 +154,4 @@ namespace XivCommon.Functions {
|
|||
Marshal.FreeHGlobal(this.textPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
/// Class containing chat bubble events and functions
|
||||
/// </summary>
|
||||
public class ChatBubbles : IDisposable {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// Class containing chat bubble events and functions
|
||||
/// </summary>
|
||||
public class ChatBubbles : IDisposable {
|
||||
private static class Signatures {
|
||||
internal const string ChatBubbleOpen = "E8 ?? ?? ?? ?? C7 43 ?? ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8";
|
||||
internal const string ChatBubbleUpdate = "48 85 D2 0F 84 ?? ?? ?? ?? 48 89 5C 24 ?? 57 48 83 EC 20 8B 41 0C";
|
||||
}
|
||||
|
||||
private ObjectTable ObjectTable { get; }
|
||||
private IObjectTable ObjectTable { get; }
|
||||
|
||||
private delegate void OpenChatBubbleDelegate(IntPtr manager, IntPtr @object, IntPtr text, byte a4);
|
||||
|
||||
|
@ -56,7 +57,7 @@ namespace XivCommon.Functions {
|
|||
/// </summary>
|
||||
public event OnUpdateChatBubbleDelegate? OnUpdateBubble;
|
||||
|
||||
internal ChatBubbles(ObjectTable objectTable, SigScanner scanner, bool hookEnabled) {
|
||||
internal ChatBubbles(IObjectTable objectTable, ISigScanner scanner, IGameInteropProvider interop, bool hookEnabled) {
|
||||
this.ObjectTable = objectTable;
|
||||
|
||||
if (!hookEnabled) {
|
||||
|
@ -64,12 +65,12 @@ namespace XivCommon.Functions {
|
|||
}
|
||||
|
||||
if (scanner.TryScanText(Signatures.ChatBubbleOpen, out var openPtr, "chat bubbles open")) {
|
||||
this.OpenChatBubbleHook = Hook<OpenChatBubbleDelegate>.FromAddress(openPtr, this.OpenChatBubbleDetour);
|
||||
this.OpenChatBubbleHook = interop.HookFromAddress<OpenChatBubbleDelegate>(openPtr, this.OpenChatBubbleDetour);
|
||||
this.OpenChatBubbleHook.Enable();
|
||||
}
|
||||
|
||||
if (scanner.TryScanText(Signatures.ChatBubbleUpdate, out var updatePtr, "chat bubbles update")) {
|
||||
this.UpdateChatBubbleHook = Hook<UpdateChatBubbleDelegate>.FromAddress(updatePtr + 9, this.UpdateChatBubbleDetour);
|
||||
this.UpdateChatBubbleHook = interop.HookFromAddress<UpdateChatBubbleDelegate>(updatePtr + 9, this.UpdateChatBubbleDetour);
|
||||
this.UpdateChatBubbleHook.Enable();
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +85,7 @@ namespace XivCommon.Functions {
|
|||
try {
|
||||
this.OpenChatBubbleDetourInner(manager, @object, text, a4);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in chat bubble detour");
|
||||
Logger.Log.Error(ex, "Exception in chat bubble detour");
|
||||
this.OpenChatBubbleHook!.Original(manager, @object, text, a4);
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +101,7 @@ namespace XivCommon.Functions {
|
|||
try {
|
||||
this.OnChatBubble?.Invoke(ref @object, ref text);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in chat bubble event");
|
||||
Logger.Log.Error(ex, "Exception in chat bubble event");
|
||||
}
|
||||
|
||||
var newText = text.Encode().Terminate();
|
||||
|
@ -116,7 +117,7 @@ namespace XivCommon.Functions {
|
|||
try {
|
||||
this.UpdateChatBubbleDetourInner(bubblePtr, @object);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in update chat bubble detour");
|
||||
Logger.Log.Error(ex, "Exception in update chat bubble detour");
|
||||
this.UpdateChatBubbleHook!.Original(bubblePtr, @object);
|
||||
}
|
||||
}
|
||||
|
@ -131,15 +132,15 @@ namespace XivCommon.Functions {
|
|||
try {
|
||||
this.OnUpdateBubble?.Invoke(ref @object);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in chat bubble update event");
|
||||
Logger.Log.Error(ex, "Exception in chat bubble update event");
|
||||
}
|
||||
|
||||
this.UpdateChatBubbleHook!.Original(bubblePtr, @object.Address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x80)]
|
||||
internal unsafe struct ChatBubble {
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x80)]
|
||||
internal unsafe struct ChatBubble {
|
||||
[FieldOffset(0x0)]
|
||||
internal readonly uint Id;
|
||||
|
||||
|
@ -157,12 +158,11 @@ namespace XivCommon.Functions {
|
|||
|
||||
[FieldOffset(0x78)]
|
||||
internal readonly ulong Unk_78; // check whats in memory here
|
||||
}
|
||||
}
|
||||
|
||||
internal enum ChatBubbleStatus : uint {
|
||||
internal enum ChatBubbleStatus : uint {
|
||||
GetData = 0,
|
||||
On = 1,
|
||||
Init = 2,
|
||||
Off = 3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
|||
using Lumina.Excel.GeneratedSheets;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
/// Duty Finder functions
|
||||
/// </summary>
|
||||
public class DutyFinder {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// Duty Finder functions
|
||||
/// </summary>
|
||||
public class DutyFinder {
|
||||
private static class Signatures {
|
||||
internal const string OpenRegularDuty = "48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 48 8B F9 41 0F B6 E8";
|
||||
internal const string OpenRoulette = "E9 ?? ?? ?? ?? 8B 93 ?? ?? ?? ?? 48 83 C4 20";
|
||||
|
@ -22,7 +23,7 @@ namespace XivCommon.Functions {
|
|||
private readonly OpenDutyDelegate? _openDuty;
|
||||
private readonly OpenRouletteDelegate? _openRoulette;
|
||||
|
||||
internal DutyFinder(SigScanner scanner) {
|
||||
internal DutyFinder(ISigScanner scanner) {
|
||||
if (scanner.TryScanText(Signatures.OpenRegularDuty, out var openDutyPtr, "Duty Finder (open duty)")) {
|
||||
this._openDuty = Marshal.GetDelegateForFunctionPointer<OpenDutyDelegate>(openDutyPtr);
|
||||
}
|
||||
|
@ -77,5 +78,4 @@ namespace XivCommon.Functions {
|
|||
|
||||
this._openRoulette(agent, roulette, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,12 @@ using Dalamud.Game;
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
/// Class containing examine functions
|
||||
/// </summary>
|
||||
public class Examine {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// Class containing examine functions
|
||||
/// </summary>
|
||||
public class Examine {
|
||||
private static class Signatures {
|
||||
internal const string RequestCharacterInfo = "40 53 48 83 EC 40 48 8B D9 48 8B 49 10 48 8B 01 FF 90 ?? ?? ?? ?? BA";
|
||||
}
|
||||
|
@ -17,7 +18,7 @@ namespace XivCommon.Functions {
|
|||
|
||||
private RequestCharInfoDelegate? RequestCharacterInfo { get; }
|
||||
|
||||
internal Examine(SigScanner scanner) {
|
||||
internal Examine(ISigScanner scanner) {
|
||||
// got this by checking what accesses rciData below
|
||||
if (scanner.TryScanText(Signatures.RequestCharacterInfo, out var rciPtr, "Examine")) {
|
||||
this.RequestCharacterInfo = Marshal.GetDelegateForFunctionPointer<RequestCharInfoDelegate>(rciPtr);
|
||||
|
@ -63,5 +64,4 @@ namespace XivCommon.Functions {
|
|||
|
||||
this.RequestCharacterInfo(rciData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@ using System.Collections.Generic;
|
|||
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
|
||||
namespace XivCommon.Functions.FriendList {
|
||||
/// <summary>
|
||||
/// The class containing friend list functionality
|
||||
/// </summary>
|
||||
public class FriendList {
|
||||
namespace XivCommon.Functions.FriendList;
|
||||
|
||||
/// <summary>
|
||||
/// The class containing friend list functionality
|
||||
/// </summary>
|
||||
public class FriendList {
|
||||
// Updated: 5.58-HF1
|
||||
private const int InfoOffset = 0x28;
|
||||
private const int LengthOffset = 0x10;
|
||||
|
@ -58,5 +59,4 @@ namespace XivCommon.Functions.FriendList {
|
|||
|
||||
internal FriendList() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,13 @@ using System.Runtime.InteropServices;
|
|||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Memory;
|
||||
|
||||
namespace XivCommon.Functions.FriendList {
|
||||
/// <summary>
|
||||
/// An entry in a player's friend list.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit, Size = Size)]
|
||||
public unsafe struct FriendListEntry {
|
||||
namespace XivCommon.Functions.FriendList;
|
||||
|
||||
/// <summary>
|
||||
/// An entry in a player's friend list.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit, Size = Size)]
|
||||
public unsafe struct FriendListEntry {
|
||||
internal const int Size = 104;
|
||||
|
||||
/// <summary>
|
||||
|
@ -68,5 +69,4 @@ namespace XivCommon.Functions.FriendList {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
using Dalamud.Game;
|
||||
|
||||
namespace XivCommon.Functions.Housing {
|
||||
/// <summary>
|
||||
/// The class containing housing functionality
|
||||
/// </summary>
|
||||
public class Housing {
|
||||
namespace XivCommon.Functions.Housing;
|
||||
|
||||
/// <summary>
|
||||
/// The class containing housing functionality
|
||||
/// </summary>
|
||||
public class Housing {
|
||||
private static class Signatures {
|
||||
internal const string HousingPointer = "48 8B 05 ?? ?? ?? ?? 48 83 78 ?? ?? 74 16 48 8D 8F ?? ?? ?? ?? 66 89 5C 24 ?? 48 8D 54 24 ?? E8 ?? ?? ?? ?? 48 8B 7C 24";
|
||||
}
|
||||
|
@ -47,10 +48,9 @@ namespace XivCommon.Functions.Housing {
|
|||
}
|
||||
}
|
||||
|
||||
internal Housing(SigScanner scanner) {
|
||||
internal Housing(ISigScanner scanner) {
|
||||
if (scanner.TryGetStaticAddressFromSig(Signatures.HousingPointer, out var ptr)) {
|
||||
this.HousingPointer = ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
namespace XivCommon.Functions.Housing {
|
||||
/// <summary>
|
||||
/// Information about a player's current location in a housing ward.
|
||||
/// </summary>
|
||||
public class HousingLocation {
|
||||
namespace XivCommon.Functions.Housing;
|
||||
|
||||
/// <summary>
|
||||
/// Information about a player's current location in a housing ward.
|
||||
/// </summary>
|
||||
public class HousingLocation {
|
||||
/// <summary>
|
||||
/// The housing ward that the player is in.
|
||||
/// </summary>
|
||||
|
@ -55,5 +56,4 @@
|
|||
this.Ward = (ushort) (ward + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace XivCommon.Functions.Housing {
|
||||
/// <summary>
|
||||
/// Information about the player's current location in a housing ward as
|
||||
/// kept by the game's internal structures.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public readonly struct RawHousingLocation {
|
||||
namespace XivCommon.Functions.Housing;
|
||||
|
||||
/// <summary>
|
||||
/// Information about the player's current location in a housing ward as
|
||||
/// kept by the game's internal structures.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public readonly struct RawHousingLocation {
|
||||
/// <summary>
|
||||
/// The zero-indexed plot number that the player is in.
|
||||
///
|
||||
|
@ -37,5 +38,4 @@ namespace XivCommon.Functions.Housing {
|
|||
/// A byte that is zero when the player is inside a plot.
|
||||
/// </summary>
|
||||
public readonly byte InsideIndicator; // aa -> ab
|
||||
}
|
||||
}
|
|
@ -5,11 +5,12 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
|||
using Lumina.Excel.GeneratedSheets;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
/// Journal functions
|
||||
/// </summary>
|
||||
public class Journal {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// Journal functions
|
||||
/// </summary>
|
||||
public class Journal {
|
||||
private static class Signatures {
|
||||
internal const string OpenQuest = "E8 ?? ?? ?? ?? 48 8B 74 24 ?? 48 8B 7C 24 ?? 48 83 C4 30 5B C3 48 8B CB";
|
||||
internal const string IsQuestCompleted = "E8 ?? ?? ?? ?? 41 88 84 2C";
|
||||
|
@ -22,7 +23,7 @@ namespace XivCommon.Functions {
|
|||
private readonly OpenQuestDelegate? _openQuest;
|
||||
private readonly IsQuestCompletedDelegate? _isQuestCompleted;
|
||||
|
||||
internal Journal(SigScanner scanner) {
|
||||
internal Journal(ISigScanner scanner) {
|
||||
if (scanner.TryScanText(Signatures.OpenQuest, out var openQuestPtr, "Journal (open quest)")) {
|
||||
this._openQuest = Marshal.GetDelegateForFunctionPointer<OpenQuestDelegate>(openQuestPtr);
|
||||
}
|
||||
|
@ -79,5 +80,4 @@ namespace XivCommon.Functions {
|
|||
|
||||
return this._isQuestCompleted((ushort) (questId & 0xFFFF)) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
|
||||
namespace XivCommon.Functions.NamePlates {
|
||||
/// <summary>
|
||||
/// Arguments for the name plate update event
|
||||
/// </summary>
|
||||
public class NamePlateUpdateEventArgs {
|
||||
namespace XivCommon.Functions.NamePlates;
|
||||
|
||||
/// <summary>
|
||||
/// Arguments for the name plate update event
|
||||
/// </summary>
|
||||
public class NamePlateUpdateEventArgs {
|
||||
/// <summary>
|
||||
/// The object ID associated with this name plate.
|
||||
/// </summary>
|
||||
|
@ -74,5 +75,4 @@ namespace XivCommon.Functions.NamePlates {
|
|||
internal NamePlateUpdateEventArgs(uint objectId) {
|
||||
this.ObjectId = objectId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,15 +3,17 @@ using System.Runtime.InteropServices;
|
|||
using Dalamud.Game;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions.NamePlates {
|
||||
/// <summary>
|
||||
/// The class containing name plate functionality
|
||||
/// </summary>
|
||||
public class NamePlates : IDisposable {
|
||||
namespace XivCommon.Functions.NamePlates;
|
||||
|
||||
/// <summary>
|
||||
/// The class containing name plate functionality
|
||||
/// </summary>
|
||||
public class NamePlates : IDisposable {
|
||||
private static class Signatures {
|
||||
internal const string NamePlateUpdate = "48 8B C4 41 56 48 81 EC ?? ?? ?? ?? 48 89 58 F0";
|
||||
}
|
||||
|
@ -46,7 +48,7 @@ namespace XivCommon.Functions.NamePlates {
|
|||
/// </summary>
|
||||
public bool ForceRedraw { get; set; }
|
||||
|
||||
internal NamePlates(GameFunctions functions, SigScanner scanner, bool hookEnabled) {
|
||||
internal NamePlates(GameFunctions functions, ISigScanner scanner, IGameInteropProvider interop, bool hookEnabled) {
|
||||
this.Functions = functions;
|
||||
|
||||
if (!hookEnabled) {
|
||||
|
@ -55,7 +57,7 @@ namespace XivCommon.Functions.NamePlates {
|
|||
|
||||
if (scanner.TryScanText(Signatures.NamePlateUpdate, out var updatePtr)) {
|
||||
unsafe {
|
||||
this._namePlateUpdateHook = Hook<NamePlateUpdateDelegate>.FromAddress(updatePtr, this.NamePlateUpdateDetour);
|
||||
this._namePlateUpdateHook = interop.HookFromAddress<NamePlateUpdateDelegate>(updatePtr, this.NamePlateUpdateDetour);
|
||||
}
|
||||
|
||||
this._namePlateUpdateHook.Enable();
|
||||
|
@ -83,7 +85,7 @@ namespace XivCommon.Functions.NamePlates {
|
|||
try {
|
||||
this.NamePlateUpdateDetourInner(numberData, stringData);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in NamePlateUpdateDetour");
|
||||
Logger.Log.Error(ex, "Exception in NamePlateUpdateDetour");
|
||||
}
|
||||
|
||||
return this._namePlateUpdateHook!.Original(addon, numberData, stringData);
|
||||
|
@ -162,7 +164,7 @@ namespace XivCommon.Functions.NamePlates {
|
|||
try {
|
||||
this.OnUpdate?.Invoke(args);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in name plate update event");
|
||||
Logger.Log.Error(ex, "Exception in name plate update event");
|
||||
}
|
||||
|
||||
void Replace(byte[] bytes, int i, bool free = true) {
|
||||
|
@ -223,5 +225,4 @@ namespace XivCommon.Functions.NamePlates {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics;
|
||||
|
||||
namespace XivCommon.Functions.NamePlates {
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x28)]
|
||||
internal unsafe struct NumberArrayData {
|
||||
namespace XivCommon.Functions.NamePlates;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x28)]
|
||||
internal unsafe struct NumberArrayData {
|
||||
[FieldOffset(0x0)]
|
||||
public AtkArrayData AtkArrayData;
|
||||
|
||||
|
@ -22,10 +23,10 @@ namespace XivCommon.Functions.NamePlates {
|
|||
this.IntArray[index] = value;
|
||||
this.AtkArrayData.HasModifiedData = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x20)]
|
||||
internal unsafe struct AtkArrayData {
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x20)]
|
||||
internal unsafe struct AtkArrayData {
|
||||
[FieldOffset(0x0)]
|
||||
public void* vtbl;
|
||||
|
||||
|
@ -43,10 +44,10 @@ namespace XivCommon.Functions.NamePlates {
|
|||
|
||||
[FieldOffset(0x1F)]
|
||||
public byte Unk1F; // initialized to -1
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x30)]
|
||||
internal unsafe struct StringArrayData {
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x30)]
|
||||
internal unsafe struct StringArrayData {
|
||||
[FieldOffset(0x0)]
|
||||
public AtkArrayData AtkArrayData;
|
||||
|
||||
|
@ -55,12 +56,12 @@ namespace XivCommon.Functions.NamePlates {
|
|||
|
||||
[FieldOffset(0x28)]
|
||||
public byte* UnkString; // char *
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The various different name plate types
|
||||
/// </summary>
|
||||
public enum PlateType {
|
||||
/// <summary>
|
||||
/// The various different name plate types
|
||||
/// </summary>
|
||||
public enum PlateType {
|
||||
/// <summary>
|
||||
/// A normal player name plate
|
||||
/// </summary>
|
||||
|
@ -90,12 +91,12 @@ namespace XivCommon.Functions.NamePlates {
|
|||
/// A name plate where the title always appears below the name and the FC tag is removed
|
||||
/// </summary>
|
||||
LowTitleNoFc = 8,
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A colour, represented in the RGBA format.
|
||||
/// </summary>
|
||||
public class RgbaColour {
|
||||
/// <summary>
|
||||
/// A colour, represented in the RGBA format.
|
||||
/// </summary>
|
||||
public class RgbaColour {
|
||||
/// <summary>
|
||||
/// The red component of the colour.
|
||||
/// </summary>
|
||||
|
@ -172,5 +173,4 @@ namespace XivCommon.Functions.NamePlates {
|
|||
A = rgba.A,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,18 +2,19 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.Gui.PartyFinder;
|
||||
using Dalamud.Game.Gui.PartyFinder.Types;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
/// A class containing Party Finder functionality
|
||||
/// </summary>
|
||||
public class PartyFinder : IDisposable {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// A class containing Party Finder functionality
|
||||
/// </summary>
|
||||
public class PartyFinder : IDisposable {
|
||||
private static class Signatures {
|
||||
internal const string RequestListings = "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 40 0F 10 81";
|
||||
internal const string JoinCrossParty = "E8 ?? ?? ?? ?? 0F B7 47 28";
|
||||
internal const string JoinCrossParty = "E8 ?? ?? ?? ?? 41 0F B7 07 49 8B CC";
|
||||
}
|
||||
|
||||
private delegate byte RequestPartyFinderListingsDelegate(IntPtr agent, byte categoryIdx);
|
||||
|
@ -39,7 +40,7 @@ namespace XivCommon.Functions {
|
|||
/// </summary>
|
||||
public event JoinPfEventDelegate? JoinParty;
|
||||
|
||||
private PartyFinderGui PartyFinderGui { get; }
|
||||
private IPartyFinderGui PartyFinderGui { get; }
|
||||
private bool JoinsEnabled { get; }
|
||||
private bool ListingsEnabled { get; }
|
||||
private IntPtr PartyFinderAgent { get; set; } = IntPtr.Zero;
|
||||
|
@ -59,7 +60,7 @@ namespace XivCommon.Functions {
|
|||
/// </summary>
|
||||
public IReadOnlyDictionary<uint, PartyFinderListing> CurrentListings => this.Listings;
|
||||
|
||||
internal PartyFinder(SigScanner scanner, PartyFinderGui partyFinderGui, Hooks hooks) {
|
||||
internal PartyFinder(ISigScanner scanner, IPartyFinderGui partyFinderGui, IGameInteropProvider interop, Hooks hooks) {
|
||||
this.PartyFinderGui = partyFinderGui;
|
||||
|
||||
this.ListingsEnabled = hooks.HasFlag(Hooks.PartyFinderListings);
|
||||
|
@ -73,13 +74,13 @@ namespace XivCommon.Functions {
|
|||
this.RequestPartyFinderListings = Marshal.GetDelegateForFunctionPointer<RequestPartyFinderListingsDelegate>(requestPfPtr);
|
||||
|
||||
if (this.ListingsEnabled) {
|
||||
this.RequestPfListingsHook = Hook<RequestPartyFinderListingsDelegate>.FromAddress(requestPfPtr, this.OnRequestPartyFinderListings);
|
||||
this.RequestPfListingsHook = interop.HookFromAddress<RequestPartyFinderListingsDelegate>(requestPfPtr, this.OnRequestPartyFinderListings);
|
||||
this.RequestPfListingsHook.Enable();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.JoinsEnabled && scanner.TryScanText(Signatures.JoinCrossParty, out var joinPtr, "Party Finder joins")) {
|
||||
this.JoinPfHook = Hook<JoinPfDelegate>.FromAddress(joinPtr, this.JoinPfDetour);
|
||||
this.JoinPfHook = interop.HookFromAddress<JoinPfDelegate>(joinPtr, this.JoinPfDetour);
|
||||
this.JoinPfHook.Enable();
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +123,7 @@ namespace XivCommon.Functions {
|
|||
this.JoinParty?.Invoke(listing);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in PF join detour");
|
||||
Logger.Log.Error(ex, "Exception in PF join detour");
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -156,9 +157,9 @@ namespace XivCommon.Functions {
|
|||
var categoryIdx = Marshal.ReadByte(this.PartyFinderAgent + categoryOffset);
|
||||
this.RequestPartyFinderListings(this.PartyFinderAgent, categoryIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum JoinType : byte {
|
||||
internal enum JoinType : byte {
|
||||
/// <summary>
|
||||
/// Join via invite or party conversion.
|
||||
/// </summary>
|
||||
|
@ -177,5 +178,4 @@ namespace XivCommon.Functions {
|
|||
LeaveDuty = 3,
|
||||
|
||||
Unknown4 = 4,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,14 @@ using System.Runtime.InteropServices;
|
|||
using Dalamud.Game;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
/// Class containing Talk events
|
||||
/// </summary>
|
||||
public class Talk : IDisposable {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// Class containing Talk events
|
||||
/// </summary>
|
||||
public class Talk : IDisposable {
|
||||
private static class Signatures {
|
||||
internal const string SetAtkValue = "E8 ?? ?? ?? ?? 41 03 ED";
|
||||
internal const string ShowMessageBox = "4C 8B DC 55 57 41 55 49 8D 6B 98";
|
||||
|
@ -42,7 +44,7 @@ namespace XivCommon.Functions {
|
|||
/// </summary>
|
||||
public event TalkEventDelegate? OnTalk;
|
||||
|
||||
internal Talk(SigScanner scanner, bool hooksEnabled) {
|
||||
internal Talk(ISigScanner scanner, IGameInteropProvider interop, bool hooksEnabled) {
|
||||
if (scanner.TryScanText(Signatures.SetAtkValue, out var setAtkPtr, "Talk - set atk value")) {
|
||||
this.SetAtkValueString = Marshal.GetDelegateForFunctionPointer<SetAtkValueStringDelegate>(setAtkPtr);
|
||||
} else {
|
||||
|
@ -54,7 +56,7 @@ namespace XivCommon.Functions {
|
|||
}
|
||||
|
||||
if (scanner.TryScanText(Signatures.ShowMessageBox, out var showMessageBoxPtr, "Talk")) {
|
||||
this.AddonTalkV45Hook = Hook<AddonTalkV45Delegate>.FromAddress(showMessageBoxPtr, this.AddonTalkV45Detour);
|
||||
this.AddonTalkV45Hook = interop.HookFromAddress<AddonTalkV45Delegate>(showMessageBoxPtr, this.AddonTalkV45Detour);
|
||||
this.AddonTalkV45Hook.Enable();
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +74,7 @@ namespace XivCommon.Functions {
|
|||
try {
|
||||
this.AddonTalkV45DetourInner(data);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in Talk detour");
|
||||
Logger.Log.Error(ex, "Exception in Talk detour");
|
||||
}
|
||||
|
||||
Return:
|
||||
|
@ -90,7 +92,7 @@ namespace XivCommon.Functions {
|
|||
try {
|
||||
this.OnTalk?.Invoke(ref name, ref text, ref style);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in Talk event");
|
||||
Logger.Log.Error(ex, "Exception in Talk event");
|
||||
}
|
||||
|
||||
var newName = name.Encode().Terminate();
|
||||
|
@ -105,12 +107,12 @@ namespace XivCommon.Functions {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Talk window styles.
|
||||
/// </summary>
|
||||
public enum TalkStyle : byte {
|
||||
/// <summary>
|
||||
/// Talk window styles.
|
||||
/// </summary>
|
||||
public enum TalkStyle : byte {
|
||||
/// <summary>
|
||||
/// The normal style with a white background.
|
||||
/// </summary>
|
||||
|
@ -155,5 +157,4 @@ namespace XivCommon.Functions {
|
|||
/// The system message style with a purple background.
|
||||
/// </summary>
|
||||
PurpleSystem = 9,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
using Dalamud.Game.Text.SeStringHandling;
|
||||
|
||||
namespace XivCommon.Functions.Tooltips {
|
||||
/// <summary>
|
||||
/// The class allowing for action tooltip manipulation
|
||||
/// </summary>
|
||||
public unsafe class ActionTooltip : BaseTooltip {
|
||||
namespace XivCommon.Functions.Tooltips;
|
||||
|
||||
/// <summary>
|
||||
/// The class allowing for action tooltip manipulation
|
||||
/// </summary>
|
||||
public unsafe class ActionTooltip : BaseTooltip {
|
||||
internal ActionTooltip(Tooltips.StringArrayDataSetStringDelegate sadSetString, byte*** stringArrayData, int** numberArrayData) : base(sadSetString, stringArrayData, numberArrayData) {
|
||||
}
|
||||
|
||||
|
@ -24,5 +25,4 @@ namespace XivCommon.Functions.Tooltips {
|
|||
get => (ActionTooltipFields) (**(this.NumberArrayData + 4));
|
||||
set => **(this.NumberArrayData + 4) = (int) value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace XivCommon.Functions.Tooltips {
|
||||
/// <summary>
|
||||
/// An enum containing the strings used in action tooltips.
|
||||
/// </summary>
|
||||
public enum ActionTooltipString {
|
||||
namespace XivCommon.Functions.Tooltips;
|
||||
|
||||
/// <summary>
|
||||
/// An enum containing the strings used in action tooltips.
|
||||
/// </summary>
|
||||
public enum ActionTooltipString {
|
||||
#pragma warning disable 1591
|
||||
Name = 0,
|
||||
Type = 1,
|
||||
|
@ -22,13 +23,13 @@ namespace XivCommon.Functions.Tooltips {
|
|||
Acquired = 14,
|
||||
Affinity = 15,
|
||||
#pragma warning restore 1591
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An enum containing the fields that can be displayed in action tooltips.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ActionTooltipFields {
|
||||
/// <summary>
|
||||
/// An enum containing the fields that can be displayed in action tooltips.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ActionTooltipFields {
|
||||
#pragma warning disable 1591
|
||||
Range = 1 << 0,
|
||||
Radius = 1 << 1,
|
||||
|
@ -40,5 +41,4 @@ namespace XivCommon.Functions.Tooltips {
|
|||
Affinity = 1 << 7,
|
||||
Unknown8 = 1 << 8,
|
||||
#pragma warning restore 1591
|
||||
}
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
|
||||
namespace XivCommon.Functions.Tooltips {
|
||||
/// <summary>
|
||||
/// The base class for tooltips
|
||||
/// </summary>
|
||||
public abstract unsafe class BaseTooltip {
|
||||
namespace XivCommon.Functions.Tooltips;
|
||||
|
||||
/// <summary>
|
||||
/// The base class for tooltips
|
||||
/// </summary>
|
||||
public abstract unsafe class BaseTooltip {
|
||||
private Tooltips.StringArrayDataSetStringDelegate SadSetString { get; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -46,5 +47,4 @@ namespace XivCommon.Functions.Tooltips {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
using Dalamud.Game.Text.SeStringHandling;
|
||||
|
||||
namespace XivCommon.Functions.Tooltips {
|
||||
/// <summary>
|
||||
/// The class allowing for item tooltip manipulation
|
||||
/// </summary>
|
||||
public unsafe class ItemTooltip : BaseTooltip {
|
||||
namespace XivCommon.Functions.Tooltips;
|
||||
|
||||
/// <summary>
|
||||
/// The class allowing for item tooltip manipulation
|
||||
/// </summary>
|
||||
public unsafe class ItemTooltip : BaseTooltip {
|
||||
internal ItemTooltip(Tooltips.StringArrayDataSetStringDelegate sadSetString, byte*** stringArrayData, int** numberArrayData) : base(sadSetString, stringArrayData, numberArrayData) {
|
||||
}
|
||||
|
||||
|
@ -24,5 +25,4 @@ namespace XivCommon.Functions.Tooltips {
|
|||
get => (ItemTooltipFields) (*(*(this.NumberArrayData + 4) + 4));
|
||||
set => *(*(this.NumberArrayData + 4) + 4) = (int) value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace XivCommon.Functions.Tooltips {
|
||||
/// <summary>
|
||||
/// An enum containing the strings used in item tooltips.
|
||||
/// </summary>
|
||||
public enum ItemTooltipString {
|
||||
namespace XivCommon.Functions.Tooltips;
|
||||
|
||||
/// <summary>
|
||||
/// An enum containing the strings used in item tooltips.
|
||||
/// </summary>
|
||||
public enum ItemTooltipString {
|
||||
#pragma warning disable 1591
|
||||
Name = 0,
|
||||
GlamourName = 1,
|
||||
|
@ -54,13 +55,13 @@ namespace XivCommon.Functions.Tooltips {
|
|||
ShopSellingPrice = 63,
|
||||
ControllerControls = 64,
|
||||
#pragma warning restore 1591
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An enum containing the fields that can be displayed in item tooltips.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ItemTooltipFields {
|
||||
/// <summary>
|
||||
/// An enum containing the fields that can be displayed in item tooltips.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ItemTooltipFields {
|
||||
#pragma warning disable 1591
|
||||
Crafter = 1 << 0,
|
||||
Description = 1 << 1,
|
||||
|
@ -90,5 +91,4 @@ namespace XivCommon.Functions.Tooltips {
|
|||
GlamourIndicator = 1 << 16,
|
||||
Unknown19 = 1 << 19,
|
||||
#pragma warning restore 1591
|
||||
}
|
||||
}
|
|
@ -3,12 +3,14 @@ using System.Runtime.InteropServices;
|
|||
using Dalamud.Game;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
||||
namespace XivCommon.Functions.Tooltips {
|
||||
/// <summary>
|
||||
/// The class containing tooltip functionality
|
||||
/// </summary>
|
||||
public class Tooltips : IDisposable {
|
||||
namespace XivCommon.Functions.Tooltips;
|
||||
|
||||
/// <summary>
|
||||
/// The class containing tooltip functionality
|
||||
/// </summary>
|
||||
public class Tooltips : IDisposable {
|
||||
private static class Signatures {
|
||||
internal const string AgentItemDetailUpdateTooltip = "E8 ?? ?? ?? ?? 48 8B 5C 24 ?? 48 89 AE ?? ?? ?? ?? 48 89 AE";
|
||||
internal const string AgentActionDetailUpdateTooltip = "E8 ?? ?? ?? ?? EB 68 FF 50 40";
|
||||
|
@ -59,11 +61,11 @@ namespace XivCommon.Functions.Tooltips {
|
|||
/// </summary>
|
||||
public event ActionTooltipEventDelegate? OnActionTooltip;
|
||||
|
||||
private GameGui GameGui { get; }
|
||||
private IGameGui GameGui { get; }
|
||||
private ItemTooltip? ItemTooltip { get; set; }
|
||||
private ActionTooltip? ActionTooltip { get; set; }
|
||||
|
||||
internal Tooltips(SigScanner scanner, GameGui gui, bool enabled) {
|
||||
internal Tooltips(ISigScanner scanner, IGameGui gui, IGameInteropProvider interop, bool enabled) {
|
||||
this.GameGui = gui;
|
||||
|
||||
if (scanner.TryScanText(Signatures.SadSetString, out var setStringPtr, "Tooltips - StringArrayData::SetString")) {
|
||||
|
@ -78,7 +80,7 @@ namespace XivCommon.Functions.Tooltips {
|
|||
|
||||
if (scanner.TryScanText(Signatures.AgentItemDetailUpdateTooltip, out var updateItemPtr, "Tooltips - Items")) {
|
||||
unsafe {
|
||||
this.ItemUpdateTooltipHook = Hook<ItemUpdateTooltipDelegate>.FromAddress(updateItemPtr, this.ItemUpdateTooltipDetour);
|
||||
this.ItemUpdateTooltipHook = interop.HookFromAddress<ItemUpdateTooltipDelegate>(updateItemPtr, this.ItemUpdateTooltipDetour);
|
||||
}
|
||||
|
||||
this.ItemUpdateTooltipHook.Enable();
|
||||
|
@ -86,7 +88,7 @@ namespace XivCommon.Functions.Tooltips {
|
|||
|
||||
if (scanner.TryScanText(Signatures.AgentActionDetailUpdateTooltip, out var updateActionPtr, "Tooltips - Actions")) {
|
||||
unsafe {
|
||||
this.ActionGenerateTooltipHook = Hook<ActionUpdateTooltipDelegate>.FromAddress(updateActionPtr, this.ActionUpdateTooltipDetour);
|
||||
this.ActionGenerateTooltipHook = interop.HookFromAddress<ActionUpdateTooltipDelegate>(updateActionPtr, this.ActionUpdateTooltipDetour);
|
||||
}
|
||||
|
||||
this.ActionGenerateTooltipHook.Enable();
|
||||
|
@ -106,7 +108,7 @@ namespace XivCommon.Functions.Tooltips {
|
|||
try {
|
||||
this.ItemUpdateTooltipDetourInner(numberArrayData, stringArrayData);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in item tooltip detour");
|
||||
Logger.Log.Error(ex, "Exception in item tooltip detour");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +121,7 @@ namespace XivCommon.Functions.Tooltips {
|
|||
try {
|
||||
this.OnItemTooltip?.Invoke(this.ItemTooltip, this.GameGui.HoveredItem);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in OnItemTooltip event");
|
||||
Logger.Log.Error(ex, "Exception in OnItemTooltip event");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +136,7 @@ namespace XivCommon.Functions.Tooltips {
|
|||
try {
|
||||
this.ActionUpdateTooltipDetourInner(numberArrayData, stringArrayData);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in action tooltip detour");
|
||||
Logger.Log.Error(ex, "Exception in action tooltip detour");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,8 +146,7 @@ namespace XivCommon.Functions.Tooltips {
|
|||
try {
|
||||
this.OnActionTooltip?.Invoke(this.ActionTooltip, this.GameGui.HoveredAction);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Exception in OnActionTooltip event");
|
||||
}
|
||||
Logger.Log.Error(ex, "Exception in OnActionTooltip event");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
internal class UiAlloc {
|
||||
namespace XivCommon.Functions;
|
||||
|
||||
internal class UiAlloc {
|
||||
private static class Signatures {
|
||||
internal const string GameAlloc = "E8 ?? ?? ?? ?? 49 83 CC FF 4C 8B F0";
|
||||
internal const string GameFree = "E8 ?? ?? ?? ?? 4C 89 7B 60";
|
||||
|
@ -22,7 +23,7 @@ namespace XivCommon.Functions {
|
|||
|
||||
private readonly GetGameAllocatorDelegate? _getGameAllocator;
|
||||
|
||||
internal UiAlloc(SigScanner scanner) {
|
||||
internal UiAlloc(ISigScanner scanner) {
|
||||
if (scanner.TryScanText(Signatures.GameAlloc, out var gameAllocPtr, "UiAlloc (GameAlloc)")) {
|
||||
this._gameAlloc = Marshal.GetDelegateForFunctionPointer<GameAllocDelegate>(gameAllocPtr);
|
||||
} else {
|
||||
|
@ -55,5 +56,4 @@ namespace XivCommon.Functions {
|
|||
|
||||
this._gameFree(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using System;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Game.Gui.PartyFinder;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using XivCommon.Functions;
|
||||
|
@ -12,14 +10,15 @@ using XivCommon.Functions.NamePlates;
|
|||
using XivCommon.Functions.Tooltips;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon {
|
||||
/// <summary>
|
||||
/// A class containing game functions
|
||||
/// </summary>
|
||||
public class GameFunctions : IDisposable {
|
||||
private GameGui GameGui { get; }
|
||||
namespace XivCommon;
|
||||
|
||||
private Dalamud.Game.Framework Framework { get; }
|
||||
/// <summary>
|
||||
/// A class containing game functions
|
||||
/// </summary>
|
||||
public class GameFunctions : IDisposable {
|
||||
private IGameGui GameGui { get; }
|
||||
|
||||
private IFramework Framework { get; }
|
||||
|
||||
internal UiAlloc UiAlloc { get; }
|
||||
|
||||
|
@ -84,22 +83,25 @@ namespace XivCommon {
|
|||
public Housing Housing { get; }
|
||||
|
||||
internal GameFunctions(Hooks hooks) {
|
||||
this.Framework = Util.GetService<Dalamud.Game.Framework>();
|
||||
this.GameGui = Util.GetService<GameGui>();
|
||||
Logger.Log = Util.GetService<IPluginLog>();
|
||||
|
||||
var objectTable = Util.GetService<ObjectTable>();
|
||||
var partyFinderGui = Util.GetService<PartyFinderGui>();
|
||||
var scanner = Util.GetService<SigScanner>();
|
||||
this.Framework = Util.GetService<IFramework>();
|
||||
this.GameGui = Util.GetService<IGameGui>();
|
||||
|
||||
var interop = Util.GetService<IGameInteropProvider>();
|
||||
var objectTable = Util.GetService<IObjectTable>();
|
||||
var partyFinderGui = Util.GetService<IPartyFinderGui>();
|
||||
var scanner = Util.GetService<ISigScanner>();
|
||||
|
||||
this.UiAlloc = new UiAlloc(scanner);
|
||||
this.Chat = new Chat(scanner);
|
||||
this.PartyFinder = new PartyFinder(scanner, partyFinderGui, hooks);
|
||||
this.BattleTalk = new BattleTalk(hooks.HasFlag(Hooks.BattleTalk));
|
||||
this.PartyFinder = new PartyFinder(scanner, partyFinderGui, interop, hooks);
|
||||
this.BattleTalk = new BattleTalk(interop, hooks.HasFlag(Hooks.BattleTalk));
|
||||
this.Examine = new Examine(scanner);
|
||||
this.Talk = new Talk(scanner, hooks.HasFlag(Hooks.Talk));
|
||||
this.ChatBubbles = new ChatBubbles(objectTable, scanner, hooks.HasFlag(Hooks.ChatBubbles));
|
||||
this.Tooltips = new Tooltips(scanner, this.GameGui, hooks.HasFlag(Hooks.Tooltips));
|
||||
this.NamePlates = new NamePlates(this, scanner, hooks.HasFlag(Hooks.NamePlates));
|
||||
this.Talk = new Talk(scanner, interop, hooks.HasFlag(Hooks.Talk));
|
||||
this.ChatBubbles = new ChatBubbles(objectTable, scanner, interop, hooks.HasFlag(Hooks.ChatBubbles));
|
||||
this.Tooltips = new Tooltips(scanner, this.GameGui, interop, hooks.HasFlag(Hooks.Tooltips));
|
||||
this.NamePlates = new NamePlates(this, scanner, interop, hooks.HasFlag(Hooks.NamePlates));
|
||||
this.DutyFinder = new DutyFinder(scanner);
|
||||
this.Journal = new Journal(scanner);
|
||||
this.FriendList = new FriendList();
|
||||
|
@ -122,7 +124,7 @@ namespace XivCommon {
|
|||
/// <returns>pointer to struct</returns>
|
||||
[Obsolete("Use Framework.Instance()")]
|
||||
public unsafe Framework* GetFramework() {
|
||||
return (Framework*) this.Framework.Address.BaseAddress;
|
||||
return FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -172,5 +174,4 @@ namespace XivCommon {
|
|||
public unsafe IntPtr GetAtkStageSingleton() {
|
||||
return (IntPtr) AtkStage.GetSingleton();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace XivCommon {
|
||||
/// <summary>
|
||||
/// Flags for which hooks to use
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum Hooks {
|
||||
namespace XivCommon;
|
||||
|
||||
/// <summary>
|
||||
/// Flags for which hooks to use
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum Hooks {
|
||||
/// <summary>
|
||||
/// No hook.
|
||||
///
|
||||
|
@ -66,9 +67,8 @@ namespace XivCommon {
|
|||
/// This hook is used in order to enable name plate functions.
|
||||
/// </summary>
|
||||
NamePlates = 1 << 7,
|
||||
}
|
||||
|
||||
internal static class HooksExt {
|
||||
internal const Hooks DefaultHooks = Hooks.None;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class HooksExt {
|
||||
internal const Hooks DefaultHooks = Hooks.None;
|
||||
}
|
|
@ -1,26 +1,7 @@
|
|||
using System;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
||||
namespace XivCommon {
|
||||
internal static class Logger {
|
||||
private static string Format(string msg) {
|
||||
return $"[XIVCommon] {msg}";
|
||||
}
|
||||
namespace XivCommon;
|
||||
|
||||
internal static void Log(string msg) {
|
||||
PluginLog.Log(Format(msg));
|
||||
}
|
||||
|
||||
internal static void LogWarning(string msg) {
|
||||
PluginLog.LogWarning(Format(msg));
|
||||
}
|
||||
|
||||
internal static void LogError(string msg) {
|
||||
PluginLog.LogError(Format(msg));
|
||||
}
|
||||
|
||||
internal static void LogError(Exception ex, string msg) {
|
||||
PluginLog.LogError(ex, Format(msg));
|
||||
}
|
||||
}
|
||||
internal static class Logger {
|
||||
internal static IPluginLog Log { get; set; } = null!;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
using System.Collections.Generic;
|
||||
using Dalamud.Game;
|
||||
|
||||
namespace XivCommon {
|
||||
internal static class SigScannerExt {
|
||||
namespace XivCommon;
|
||||
|
||||
internal static class SigScannerExt {
|
||||
/// <summary>
|
||||
/// Scan for a signature in memory.
|
||||
/// </summary>
|
||||
|
@ -12,7 +13,7 @@ namespace XivCommon {
|
|||
/// <param name="result">pointer where signature was found or <see cref="IntPtr.Zero"/> if not found</param>
|
||||
/// <param name="name">name of this signature - if specified, a warning will be printed if the signature could not be found</param>
|
||||
/// <returns>true if signature was found</returns>
|
||||
internal static bool TryScanText(this SigScanner scanner, string sig, out IntPtr result, string? name = null) {
|
||||
internal static bool TryScanText(this ISigScanner scanner, string sig, out IntPtr result, string? name = null) {
|
||||
result = IntPtr.Zero;
|
||||
try {
|
||||
result = scanner.ScanText(sig);
|
||||
|
@ -25,5 +26,4 @@ namespace XivCommon {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,9 @@ using System.Reflection;
|
|||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Plugin;
|
||||
|
||||
namespace XivCommon {
|
||||
internal static class Util {
|
||||
namespace XivCommon;
|
||||
|
||||
internal static class Util {
|
||||
internal static byte[] Terminate(this byte[] array) {
|
||||
var terminated = new byte[array.Length + 1];
|
||||
Array.Copy(array, terminated, array.Length);
|
||||
|
@ -36,7 +37,7 @@ namespace XivCommon {
|
|||
}
|
||||
|
||||
internal static void PrintMissingSig(string name) {
|
||||
Logger.LogWarning($"Could not find signature for {name}. This functionality will be disabled.");
|
||||
Logger.Log.Warning($"Could not find signature for {name}. This functionality will be disabled.");
|
||||
}
|
||||
|
||||
internal static T GetService<T>() {
|
||||
|
@ -59,5 +60,4 @@ namespace XivCommon {
|
|||
|
||||
return start;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<LangVersion>latest</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>7.0.2</Version>
|
||||
<Version>8.0.0</Version>
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
|||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<Title>XivCommon</Title>
|
||||
<Authors>ascclemens</Authors>
|
||||
<RepositoryUrl>https://git.annaclemens.io/ascclemens/XivCommon</RepositoryUrl>
|
||||
<RepositoryUrl>https://git.anna.lgbt/anna/XivCommon</RepositoryUrl>
|
||||
<Description>A set of common functions, hooks, and events not included in Dalamud.</Description>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace XivCommon {
|
||||
/// <summary>
|
||||
/// A base class for accessing XivCommon functionality.
|
||||
/// </summary>
|
||||
public class XivCommonBase : IDisposable {
|
||||
namespace XivCommon;
|
||||
|
||||
/// <summary>
|
||||
/// A base class for accessing XivCommon functionality.
|
||||
/// </summary>
|
||||
public class XivCommonBase : IDisposable {
|
||||
/// <summary>
|
||||
/// Game functions and events
|
||||
/// </summary>
|
||||
|
@ -27,5 +28,4 @@ namespace XivCommon {
|
|||
public void Dispose() {
|
||||
this.Functions.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue