Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

Commit

Permalink
Update CopyChara, UpdateChara
Browse files Browse the repository at this point in the history
  • Loading branch information
chirpxiv committed Oct 9, 2023
1 parent 3d63b21 commit 5556d08
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 62 deletions.
100 changes: 41 additions & 59 deletions PalettePlus/Interop/Hooks.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;

using Dalamud.Hooking;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Utility.Signatures;

using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using CSGameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;

using PalettePlus.Structs;
Expand All @@ -14,70 +15,49 @@
using PalettePlus.Palettes;

namespace PalettePlus.Interop {
internal static class Hooks {
private const string QWordSig = "4C 8B C0 48 8B 0D ?? ?? ?? ??";
private const string UpdateColorsSig = "E8 ?? ?? ?? ?? B2 FF 48 8B CB";
private const string GenerateColorsSig = "48 8B C4 4C 89 40 18 48 89 50 10 55 53";
private const string EnableDrawSig = "E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9 74 33 45 33 C0";
private const string CopyCharaSig = "E8 ?? ?? ?? ?? 0F B6 9F ?? ?? ?? ?? 48 8D 8F";
private const string UpdateCharaSig = "E8 ?? ?? ?? ?? 83 BF ?? ?? ?? ?? ?? 75 34";

internal class Hooks {
internal static Dictionary<int, int> ActorCopy = new();

internal static nint UnknownQWord;

internal unsafe delegate nint UpdateColorsDelegate(Model* a1);
[Signature("E8 ?? ?? ?? ?? B2 FF 48 8B CB")]
internal static UpdateColorsDelegate UpdateColors = null!;
//internal static Hook<UpdateColorsDelegate> UpdateColorsHook = null!;

internal unsafe delegate nint GenerateColorsDelegate(IntPtr a1, ModelShader* model, ModelShader* decal, byte* customize);
internal unsafe delegate nint UpdateColorsDelegate(Model* a1);
[Signature("48 8B C4 4C 89 40 18 48 89 50 10 55 53")]
internal static GenerateColorsDelegate GenerateColors = null!;
internal unsafe delegate nint GenerateColorsDelegate(CharacterUtility* a1, ModelShader* model, ModelShader* decal, byte* customize);

[Signature("E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9 74 33 45 33 C0", DetourName = nameof(EnableDrawDetour))]
private Hook<EnableDrawDelegate> EnableDrawHook = null!;
private unsafe delegate nint EnableDrawDelegate(CSGameObject* a1);
private static Hook<EnableDrawDelegate> EnableDrawHook = null!;

private delegate nint CopyCharaDelegate(nint to, nint from, uint unk);
private static Hook<CopyCharaDelegate> CopyCharaHook = null!;

private delegate nint UpdateCharaDelegate(nint drawObj, nint data, char skipEquip);
private static Hook<UpdateCharaDelegate> UpdateCharaHook = null!;

internal unsafe static void Init() {
UnknownQWord = *(IntPtr*)PluginServices.SigScanner.GetStaticAddressFromSig(QWordSig);

var updateColors = PluginServices.SigScanner.ScanText(UpdateColorsSig);
UpdateColors = Marshal.GetDelegateForFunctionPointer<UpdateColorsDelegate>(updateColors);
//UpdateColorsHook = Hook<UpdateColorsDelegate>.FromAddress(updateColors, UpdateColorsDetour);
//UpdateColorsHook.Enable();

var generateColors = PluginServices.SigScanner.ScanText(GenerateColorsSig);
GenerateColors = Marshal.GetDelegateForFunctionPointer<GenerateColorsDelegate>(generateColors);

EnableDrawHook = PluginServices.Hooks.HookFromSignature<EnableDrawDelegate>(EnableDrawSig, EnableDrawDetour);
EnableDrawHook.Enable();

CopyCharaHook = PluginServices.Hooks.HookFromSignature<CopyCharaDelegate>(CopyCharaSig, CopyCharaDetour);
CopyCharaHook.Enable();

UpdateCharaHook = PluginServices.Hooks.HookFromSignature<UpdateCharaDelegate>(UpdateCharaSig, UpdateCharaDetour);
UpdateCharaHook.Enable();
}

internal static void Dispose() {
//UpdateColorsHook.Disable();
//UpdateColorsHook.Dispose();
[Signature("E8 ?? ?? ?? ?? 0F B6 9F ?? ?? ?? ?? 48 8D 8F", DetourName = nameof(CopyCharaDetour))]
private Hook<CopyCharaDelegate> CopyCharaHook = null!;
private unsafe delegate nint CopyCharaDelegate(CharaSetup* to, nint from, uint unk);

[Signature("E8 ?? ?? ?? ?? 83 BF ?? ?? ?? ?? ?? 75 34", DetourName = nameof(UpdateCharaDetour))]
private Hook<UpdateCharaDelegate> UpdateCharaHook = null!;
private delegate bool UpdateCharaDelegate(nint drawObj, nint data, char skipEquip);

internal void Init() {
PluginServices.Hooks.InitializeFromAttributes(this);

this.EnableDrawHook.Enable();
this.CopyCharaHook.Enable();
this.UpdateCharaHook.Enable();
}

EnableDrawHook.Disable();
EnableDrawHook.Dispose();
internal void Dispose() {
this.EnableDrawHook.Disable();
this.EnableDrawHook.Dispose();

CopyCharaHook.Disable();
CopyCharaHook.Dispose();
this.CopyCharaHook.Disable();
this.CopyCharaHook.Dispose();

UpdateCharaHook.Disable();
UpdateCharaHook.Dispose();
this.UpdateCharaHook.Disable();
this.UpdateCharaHook.Dispose();
}

private unsafe static nint EnableDrawDetour(CSGameObject* a1) {
private unsafe nint EnableDrawDetour(CSGameObject* a1) {
var c1 = ((byte)a1->TargetableStatus & 0x80) != 0;
var c2 = (a1->RenderFlags & 0x2000000) == 0;
var isNew = !(c1 && c2);
Expand All @@ -97,11 +77,13 @@ internal static class Hooks {
return exec;
}

private static nint CopyCharaDetour(nint to, nint from, uint unk) {
private unsafe nint CopyCharaDetour(CharaSetup* to, nint from, uint unk) {
var exec = CopyCharaHook.Original(to, from, unk);

try {
var toObj = PluginServices.ObjectTable.CreateObjectReference(to) as Character;
var toAddr = to != null ? (nint)to->Character : nint.Zero;

var toObj = PluginServices.ObjectTable.CreateObjectReference(toAddr) as Character;
var fromObj = PluginServices.ObjectTable.CreateObjectReference(from) as Character;
if (toObj != null && fromObj != null && toObj.ObjectIndex >= 200 && toObj.ObjectIndex < 240) {
PluginServices.Log.Verbose($"Copying from {fromObj.ObjectIndex} to {toObj.ObjectIndex}");
Expand All @@ -114,7 +96,7 @@ internal static class Hooks {
return exec;
}

private unsafe static nint UpdateCharaDetour(nint drawObj, nint data, char skipEquip) {
private unsafe bool UpdateCharaDetour(nint drawObj, nint data, char skipEquip) {
try {
var owner = GetOwner(drawObj);
var palette = owner != null ? GetPalette(owner) : null;
Expand Down Expand Up @@ -143,7 +125,7 @@ internal static class Hooks {
return UpdateCharaHook.Original(drawObj, data, skipEquip);
}

private unsafe static Character? GetOwner(nint drawObj) {
private unsafe Character? GetOwner(nint drawObj) {
var charas = PluginServices.ObjectTable
.Where(obj => obj is Character)
.Cast<Character>();
Expand All @@ -157,7 +139,7 @@ internal static class Hooks {
return null;
}

private static Palette? GetPalette(Character chara) {
private Palette? GetPalette(Character chara) {
if (!chara.IsValidForPalette())
return null;

Expand Down
7 changes: 5 additions & 2 deletions PalettePlus/PalettePlus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ public sealed class PalettePlus : IDalamudPlugin {

public static Configuration Config { get; internal set; } = null!;

private Hooks Hooks;

public PalettePlus(DalamudPluginInterface api) {
PluginServices.Init(api);

Configuration.LoadConfig();

Hooks.Init();
this.Hooks = new Hooks();
this.Hooks.Init();

IpcProvider.Init();

Expand All @@ -43,7 +46,7 @@ public sealed class PalettePlus : IDalamudPlugin {
public void Dispose() {
IpcProvider.Dispose();

Hooks.Dispose();
this.Hooks.Dispose();

PluginServices.Interface.UiBuilder.Draw -= PluginGui.Windows.Draw;

Expand Down
2 changes: 1 addition & 1 deletion PalettePlus/Structs/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public struct Model {
decal.Pointers[i] = (ulong)decal.Parameters;
}

Interop.Hooks.GenerateColors!(Interop.Hooks.UnknownQWord, &model, &decal, custom);
Interop.Hooks.GenerateColors(CharacterUtility.Instance(), &model, &decal, custom);
}
}

Expand Down

0 comments on commit 5556d08

Please sign in to comment.