punish v6.8.18.0
This commit is contained in:
commit
cfb4dea47e
316 changed files with 554088 additions and 0 deletions
195
Questionable/Questionable.Controller/InterruptHandler.cs
Normal file
195
Questionable/Questionable.Controller/InterruptHandler.cs
Normal file
|
@ -0,0 +1,195 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Common.Math;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Questionable.Data;
|
||||
|
||||
namespace Questionable.Controller;
|
||||
|
||||
internal sealed class InterruptHandler : IDisposable
|
||||
{
|
||||
private unsafe delegate void ProcessActionEffect(uint sourceId, Character* sourceCharacter, Vector3* pos, EffectHeader* effectHeader, EffectEntry* effectArray, ulong* effectTail);
|
||||
|
||||
private static class Signatures
|
||||
{
|
||||
internal const string ActionEffect = "40 ?? 56 57 41 ?? 41 ?? 41 ?? 48 ?? ?? ?? ?? ?? ?? ?? 48";
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private struct EffectEntry
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public EActionEffectType Type;
|
||||
|
||||
[FieldOffset(1)]
|
||||
public byte Param0;
|
||||
|
||||
[FieldOffset(2)]
|
||||
public byte Param1;
|
||||
|
||||
[FieldOffset(3)]
|
||||
public byte Param2;
|
||||
|
||||
[FieldOffset(4)]
|
||||
public byte Mult;
|
||||
|
||||
[FieldOffset(5)]
|
||||
public byte Flags;
|
||||
|
||||
[FieldOffset(6)]
|
||||
public ushort Value;
|
||||
|
||||
public byte AttackType => (byte)(Param1 & 0xF);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Type: {Type}, p0: {Param0:D3}, p1: {Param1:D3}, p2: {Param2:D3} 0x{Param2:X2} '{Convert.ToString(Param2, 2).PadLeft(8, '0')}', mult: {Mult:D3}, flags: {Flags:D3} | {Convert.ToString(Flags, 2).PadLeft(8, '0')}, value: {Value:D6} ATTACK TYPE: {AttackType}";
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private struct EffectHeader
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public ulong AnimationTargetId;
|
||||
|
||||
[FieldOffset(8)]
|
||||
public uint ActionID;
|
||||
|
||||
[FieldOffset(12)]
|
||||
public uint GlobalEffectCounter;
|
||||
|
||||
[FieldOffset(16)]
|
||||
public float AnimationLockTime;
|
||||
|
||||
[FieldOffset(20)]
|
||||
public uint SomeTargetID;
|
||||
|
||||
[FieldOffset(24)]
|
||||
public ushort SourceSequence;
|
||||
|
||||
[FieldOffset(26)]
|
||||
public ushort Rotation;
|
||||
|
||||
[FieldOffset(28)]
|
||||
public ushort AnimationId;
|
||||
|
||||
[FieldOffset(30)]
|
||||
public byte Variation;
|
||||
|
||||
[FieldOffset(31)]
|
||||
public ActionType ActionType;
|
||||
|
||||
[FieldOffset(33)]
|
||||
public byte TargetCount;
|
||||
}
|
||||
|
||||
private enum EActionEffectType : byte
|
||||
{
|
||||
None = 0,
|
||||
Miss = 1,
|
||||
FullResist = 2,
|
||||
Damage = 3,
|
||||
Heal = 4,
|
||||
BlockedDamage = 5,
|
||||
ParriedDamage = 6,
|
||||
Invulnerable = 7,
|
||||
NoEffectText = 8,
|
||||
Unknown0 = 9,
|
||||
MpLoss = 10,
|
||||
MpGain = 11,
|
||||
TpLoss = 12,
|
||||
TpGain = 13,
|
||||
ApplyStatusEffectTarget = 14,
|
||||
ApplyStatusEffectSource = 15,
|
||||
RecoveredFromStatusEffect = 16,
|
||||
LoseStatusEffectTarget = 17,
|
||||
LoseStatusEffectSource = 18,
|
||||
StatusNoEffect = 20,
|
||||
ThreatPosition = 24,
|
||||
EnmityAmountUp = 25,
|
||||
EnmityAmountDown = 26,
|
||||
StartActionCombo = 27,
|
||||
ComboSucceed = 28,
|
||||
Retaliation = 29,
|
||||
Knockback = 32,
|
||||
Attract1 = 33,
|
||||
Attract2 = 34,
|
||||
Mount = 40,
|
||||
FullResistStatus = 52,
|
||||
FullResistStatus2 = 55,
|
||||
VFX = 59,
|
||||
Gauge = 60,
|
||||
JobGauge = 61,
|
||||
SetModelState = 72,
|
||||
SetHP = 73,
|
||||
PartialInvulnerable = 74,
|
||||
Interrupt = 75
|
||||
}
|
||||
|
||||
private readonly Hook<ProcessActionEffect> _processActionEffectHook;
|
||||
|
||||
private readonly IClientState _clientState;
|
||||
|
||||
private readonly TerritoryData _territoryData;
|
||||
|
||||
private readonly ILogger<InterruptHandler> _logger;
|
||||
|
||||
public event EventHandler? Interrupted;
|
||||
|
||||
public unsafe InterruptHandler(IGameInteropProvider gameInteropProvider, IClientState clientState, TerritoryData territoryData, ILogger<InterruptHandler> logger)
|
||||
{
|
||||
_clientState = clientState;
|
||||
_territoryData = territoryData;
|
||||
_logger = logger;
|
||||
_processActionEffectHook = gameInteropProvider.HookFromSignature<ProcessActionEffect>("40 ?? 56 57 41 ?? 41 ?? 41 ?? 48 ?? ?? ?? ?? ?? ?? ?? 48", HandleProcessActionEffect);
|
||||
_processActionEffectHook.Enable();
|
||||
}
|
||||
|
||||
private unsafe void HandleProcessActionEffect(uint sourceId, Character* sourceCharacter, Vector3* pos, EffectHeader* effectHeader, EffectEntry* effectArray, ulong* effectTail)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_territoryData.IsDutyInstance(_clientState.TerritoryType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < effectHeader->TargetCount; i++)
|
||||
{
|
||||
int num = (int)(effectTail[i] & 0xFFFFFFFFu);
|
||||
EffectEntry* ptr = effectArray + 8 * i;
|
||||
bool flag = (uint)num == _clientState.LocalPlayer?.GameObjectId;
|
||||
if (flag)
|
||||
{
|
||||
EActionEffectType type = ptr->Type;
|
||||
bool flag2 = ((type == EActionEffectType.Damage || type - 5 <= EActionEffectType.Miss) ? true : false);
|
||||
flag = flag2;
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
_logger.LogTrace("Damage action effect on self, from {SourceId} ({EffectType})", sourceId, ptr->Type);
|
||||
this.Interrupted?.Invoke(this, EventArgs.Empty);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogWarning(exception, "Unable to process action effect");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_processActionEffectHook.Original(sourceId, sourceCharacter, pos, effectHeader, effectArray, effectTail);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_processActionEffectHook.Disable();
|
||||
_processActionEffectHook.Dispose();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue