Code commit

This commit is contained in:
RisaDev
2024-01-06 01:21:41 +03:00
parent a7d7297c59
commit a486dd2c96
90 changed files with 11576 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
using Dalamud.Game;
namespace CustomizePlus.Game.Services.GPose.ExternalTools;
/// <summary>
/// Service which detects if Anamnesis/Ktisis posing mode is enabled.
/// </summary>
public class PosingModeDetectService
{
// Borrowed from Ktisis:
// If this is NOP'd, Anam posing is enabled.
internal static unsafe byte* AnamnesisFreezePosition;
internal static unsafe byte* AnamnesisFreezeRotation;
internal static unsafe byte* AnamnesisFreezeScale;
internal static unsafe bool IsAnamnesisPositionFrozen =>
AnamnesisFreezePosition != null && *AnamnesisFreezePosition == 0x90 || *AnamnesisFreezePosition == 0x00;
internal static unsafe bool IsAnamnesisRotationFrozen =>
AnamnesisFreezeRotation != null && *AnamnesisFreezeRotation == 0x90 || *AnamnesisFreezeRotation == 0x00;
internal static unsafe bool IsAnamnesisScalingFrozen =>
AnamnesisFreezeScale != null && *AnamnesisFreezeScale == 0x90 || *AnamnesisFreezeScale == 0x00;
internal static bool IsAnamnesis =>
IsAnamnesisPositionFrozen || IsAnamnesisRotationFrozen || IsAnamnesisScalingFrozen;
public bool IsInPosingMode => IsAnamnesis; //Can't detect Ktisis for now
public unsafe PosingModeDetectService(ISigScanner sigScanner)
{
AnamnesisFreezePosition = (byte*)sigScanner.ScanText("41 0F 29 24 12");
AnamnesisFreezeRotation = (byte*)sigScanner.ScanText("41 0F 29 5C 12 10");
AnamnesisFreezeScale = (byte*)sigScanner.ScanText("41 0F 29 44 12 20");
}
}

View File

@@ -0,0 +1,138 @@
using System;
using Dalamud.Hooking;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using OtterGui.Log;
using CustomizePlus.Game.Events;
namespace CustomizePlus.Game.Services.GPose;
public class GPoseService : IDisposable
{
private readonly ChatService _chatService;
private readonly GPoseStateChanged _event;
private readonly Logger _logger;
private Hook<EnterGPoseDelegate>? _enterGPoseHook;
private Hook<ExitGPoseDelegate>? _exitGPoseHook;
private bool _fakeGPose;
public GPoseState GPoseState { get; private set; }
public bool IsInGPose => GPoseState == GPoseState.Inside;
public bool FakeGPose
{
get => _fakeGPose;
set
{
if (value != _fakeGPose)
{
if (!value)
{
_fakeGPose = false;
HandleGPoseChange(GPoseState.Exiting);
HandleGPoseChange(GPoseState.Outside);
}
else
{
HandleGPoseChange(GPoseState.Inside);
_fakeGPose = true;
}
}
}
}
public unsafe GPoseService(
IClientState clientState,
IGameInteropProvider hooker,
ChatService chatService,
GPoseStateChanged @event,
Logger logger)
{
_chatService = chatService;
_event = @event;
_logger = logger;
GPoseState = clientState.IsGPosing ? GPoseState.Inside : GPoseState.Outside;
var uiModule = Framework.Instance()->GetUiModule();
var enterGPoseAddress = (nint)uiModule->VTable->EnterGPose;
var exitGPoseAddress = (nint)uiModule->VTable->ExitGPose;
_enterGPoseHook = hooker.HookFromAddress<EnterGPoseDelegate>(enterGPoseAddress, EnteringGPoseDetour);
_enterGPoseHook.Enable();
_exitGPoseHook = hooker.HookFromAddress<ExitGPoseDelegate>(exitGPoseAddress, ExitingGPoseDetour);
_exitGPoseHook.Enable();
}
private void ExitingGPoseDetour(nint addr)
{
if (HandleGPoseChange(GPoseState.AttemptExit))
{
HandleGPoseChange(GPoseState.Exiting);
_exitGPoseHook!.Original.Invoke(addr);
HandleGPoseChange(GPoseState.Outside);
}
}
private bool EnteringGPoseDetour(nint addr)
{
var didEnter = _enterGPoseHook!.Original.Invoke(addr);
if (didEnter)
{
_fakeGPose = false;
HandleGPoseChange(GPoseState.Inside);
}
return didEnter;
}
private bool HandleGPoseChange(GPoseState state)
{
if (state == GPoseState || _fakeGPose)
{
return true;
}
GPoseState = state;
switch (state)
{
case GPoseState.Inside:
_event.Invoke(GPoseStateChanged.Type.Entered);
break;
case GPoseState.AttemptExit:
_event.Invoke(GPoseStateChanged.Type.AttemptingExit);
break;
case GPoseState.Exiting:
_event.Invoke(GPoseStateChanged.Type.Exiting);
break;
case GPoseState.Outside:
_event.Invoke(GPoseStateChanged.Type.Exited);
break;
}
return true;
}
public void Dispose()
{
_exitGPoseHook?.Dispose();
_enterGPoseHook?.Dispose();
}
private delegate void ExitGPoseDelegate(nint addr);
private delegate bool EnterGPoseDelegate(nint addr);
}
public enum GPoseState
{
Inside,
AttemptExit,
Exiting,
Outside
}