-
-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathGame.cs
More file actions
127 lines (107 loc) · 7.06 KB
/
Game.cs
File metadata and controls
127 lines (107 loc) · 7.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Numerics;
using Dalamud.Hooking;
using FFXIVClientStructs.FFXIV.Application.Network;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
namespace NoClippy
{
public static unsafe class Game
{
public static Structures.ActionManager* actionManager;
public const float DefaultClientAnimationLock = 0.5f;
public delegate void UseActionEventDelegate(ActionManager* actionManager, ActionType actionType, uint actionId, ulong targetId, uint extraParam, ActionManager.UseActionMode mode, uint comboRouteId, bool* outOptAreaTargeted, bool ret);
public static event UseActionEventDelegate OnUseAction;
private static Hook<ActionManager.Delegates.UseAction> UseActionHook;
private static bool UseActionDetour(ActionManager* thisPtr, ActionType actionType, uint actionId, ulong targetId, uint extraParam, ActionManager.UseActionMode mode, uint comboRouteId, bool* outOptAreaTargeted)
{
var ret = UseActionHook.Original(thisPtr, actionType, actionId, targetId, extraParam, mode, comboRouteId, outOptAreaTargeted);
OnUseAction?.Invoke(thisPtr, actionType, actionId, targetId, extraParam, mode, comboRouteId, outOptAreaTargeted, ret);
return ret;
}
public delegate void UseActionLocationEventDelegate(nint actionManager, uint actionType, uint actionID, ulong targetedActorID, nint vectorLocation, uint param, byte ret);
public static event UseActionLocationEventDelegate OnUseActionLocation;
private delegate byte UseActionLocationDelegate(nint actionManager, uint actionType, uint actionID, ulong targetedActorID, nint vectorLocation, uint param, byte c);
private static Hook<UseActionLocationDelegate> UseActionLocationHook;
private static byte UseActionLocationDetour(nint actionManager, uint actionType, uint actionID, ulong targetedActorID, nint vectorLocation, uint param, byte c)
{
var ret = UseActionLocationHook.Original(actionManager, actionType, actionID, targetedActorID, vectorLocation, param, c);
OnUseActionLocation?.Invoke(actionManager, actionType, actionID, targetedActorID, vectorLocation, param, ret);
return ret;
}
private static bool invokeCastInterrupt = false;
public delegate void CastBeginDelegate(ulong objectID, nint packetData);
public static event CastBeginDelegate OnCastBegin;
private static Hook<CastBeginDelegate> CastBeginHook;
private static void CastBeginDetour(ulong objectID, nint packetData)
{
CastBeginHook.Original(objectID, packetData);
if (objectID != DalamudApi.ObjectTable.LocalPlayer?.GameObjectId) return;
OnCastBegin?.Invoke(objectID, packetData);
invokeCastInterrupt = true;
}
// Seems to always be called twice?
public delegate void CastInterruptDelegate(nint actionManager);
public static event CastInterruptDelegate OnCastInterrupt;
private static Hook<CastInterruptDelegate> CastInterruptHook;
private static void CastInterruptDetour(nint actionManager)
{
CastInterruptHook.Original(actionManager);
if (!invokeCastInterrupt) return;
OnCastInterrupt?.Invoke(actionManager);
invokeCastInterrupt = false;
}
public delegate void ReceiveActionEffectEventDelegate(uint casterEntityId, Character* casterPtr, Vector3* targetPos, ActionEffectHandler.Header* header, ActionEffectHandler.TargetEffects* effects, GameObjectId* targetEntityIds, float oldLock, float newLock);
public static event ReceiveActionEffectEventDelegate OnReceiveActionEffect;
private static Hook<ActionEffectHandler.Delegates.Receive> ReceiveActionEffectHook;
private static void ReceiveActionEffectDetour(uint casterEntityId, Character* casterPtr, Vector3* targetPos, ActionEffectHandler.Header* header, ActionEffectHandler.TargetEffects* effects, GameObjectId* targetEntityIds)
{
var oldLock = actionManager->animationLock;
ReceiveActionEffectHook.Original(casterEntityId, casterPtr, targetPos, header, effects, targetEntityIds);
OnReceiveActionEffect?.Invoke(casterEntityId, casterPtr, targetPos, header, effects, targetEntityIds, oldLock, actionManager->animationLock);
}
private static Hook<ZoneClient.Delegates.SendPacket> SendPacketHook;
public delegate void NetworkMessageEventDelegate();
public static event NetworkMessageEventDelegate OnNetworkMessageDelegate;
private static bool SendPacketDetour(ZoneClient* zoneClient, nint packet, uint a3, uint a4, bool a5)
{
OnNetworkMessageDelegate?.Invoke();
return SendPacketHook.Original(zoneClient, packet, a3, a4, a5);
}
public static void Initialize()
{
actionManager = (Structures.ActionManager*)ActionManager.Instance();
UseActionHook = DalamudApi.GameInteropProvider.HookFromAddress<ActionManager.Delegates.UseAction>((nint)ActionManager.MemberFunctionPointers.UseAction, UseActionDetour);
UseActionLocationHook = DalamudApi.GameInteropProvider.HookFromAddress<UseActionLocationDelegate>((nint)ActionManager.MemberFunctionPointers.UseActionLocation, UseActionLocationDetour);
CastBeginHook = DalamudApi.GameInteropProvider.HookFromAddress<CastBeginDelegate>(DalamudApi.SigScanner.ScanText("40 53 57 48 81 EC ?? ?? ?? ?? 48 8B FA 8B D1"), CastBeginDetour); // Bad sig, found within ActorCast packet
CastInterruptHook = DalamudApi.GameInteropProvider.HookFromAddress<CastInterruptDelegate>(DalamudApi.SigScanner.ScanText("48 8B C4 48 83 EC 48 48 89 58 08"), CastInterruptDetour);
ReceiveActionEffectHook = DalamudApi.GameInteropProvider.HookFromAddress<ActionEffectHandler.Delegates.Receive>(ActionEffectHandler.Addresses.Receive.Value, ReceiveActionEffectDetour);
SendPacketHook = DalamudApi.GameInteropProvider.HookFromAddress<ZoneClient.Delegates.SendPacket>((nint)ZoneClient.MemberFunctionPointers.SendPacket, SendPacketDetour);
UseActionHook.Enable();
UseActionLocationHook.Enable();
CastBeginHook.Enable();
CastInterruptHook.Enable();
ReceiveActionEffectHook.Enable();
SendPacketHook.Enable();
}
public static event Action OnUpdate;
public static void Update() => OnUpdate?.Invoke();
public static void Dispose()
{
UseActionHook?.Dispose();
OnUseAction = null;
UseActionLocationHook?.Dispose();
OnUseActionLocation = null;
CastBeginHook?.Dispose();
OnCastBegin = null;
CastInterruptHook?.Dispose();
OnCastInterrupt = null;
ReceiveActionEffectHook?.Dispose();
OnReceiveActionEffect = null;
SendPacketHook?.Dispose();
OnNetworkMessageDelegate = null;
OnUpdate = null;
}
}
}