diff --git a/Glamourer/Api/StateApi.cs b/Glamourer/Api/StateApi.cs
index 331942b..ce7d226 100644
--- a/Glamourer/Api/StateApi.cs
+++ b/Glamourer/Api/StateApi.cs
@@ -333,6 +333,8 @@ public sealed class StateApi : IGlamourerApiState, IApiService, IDisposable
private void OnStateChanged(StateChangeType type, StateSource _2, ActorState _3, ActorData actors, ITransaction? _5)
{
+ Glamourer.Log.Error($"[OnStateChanged API CALL] Sending out OnStateChanged with type {type}.");
+
if (StateChanged != null)
foreach (var actor in actors.Objects)
StateChanged.Invoke(actor.Address);
diff --git a/Glamourer/Automation/AutoDesignApplier.cs b/Glamourer/Automation/AutoDesignApplier.cs
index 660acf4..d49864f 100644
--- a/Glamourer/Automation/AutoDesignApplier.cs
+++ b/Glamourer/Automation/AutoDesignApplier.cs
@@ -1,4 +1,5 @@
using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
using Glamourer.Designs;
using Glamourer.Designs.Links;
@@ -201,11 +202,22 @@ public sealed class AutoDesignApplier : IDisposable
}
}
+ ///
+ /// JOB CHANGE IS CALLED UPON HERE.
+ ///
private void OnJobChange(Actor actor, Job oldJob, Job newJob)
{
+ unsafe
+ {
+ var drawObject = actor.AsCharacter->DrawObject;
+ Glamourer.Log.Information($"[AutoDesignApplier][OnJobChange] 0x{(nint)drawObject:X} changed job from {oldJob} ({oldJob.Id}) to {newJob} ({newJob.Id}).");
+ }
+
if (!_config.EnableAutoDesigns || !actor.Identifier(_actors, out var id))
return;
+ Glamourer.Log.Information($"[AutoDesignApplier][OnJobChange] We had EnableAutoDesigns active, and are a valid actor!");
+
if (!GetPlayerSet(id, out var set))
{
if (_state.TryGetValue(id, out var s))
diff --git a/Glamourer/Interop/ChangeCustomizeService.cs b/Glamourer/Interop/ChangeCustomizeService.cs
index 495d69c..032412e 100644
--- a/Glamourer/Interop/ChangeCustomizeService.cs
+++ b/Glamourer/Interop/ChangeCustomizeService.cs
@@ -64,12 +64,13 @@ public unsafe class ChangeCustomizeService : EventWrapperRef2 _changeCustomizeHook;
+ // manual invoke by calling the detours _original call to `execute to` instead of `listen to`.
public bool UpdateCustomize(Model model, CustomizeArray customize)
{
if (!model.IsHuman)
return false;
- Glamourer.Log.Verbose($"[ChangeCustomize] Invoked on 0x{model.Address:X} with {customize}.");
+ Glamourer.Log.Information($"[ChangeCustomize] Glamour-Invoked on 0x{model.Address:X} with {customize}.");
using var _ = InUpdate.EnterMethod();
var ret = _original(model.AsHuman, customize.Data, true);
return ret;
@@ -78,16 +79,20 @@ public unsafe class ChangeCustomizeService : EventWrapperRef2 UpdateCustomize(actor.Model, customize);
+ // detoured method.
private bool ChangeCustomizeDetour(Human* human, byte* data, byte skipEquipment)
{
if (!InUpdate.InMethod)
Invoke(human, ref *(CustomizeArray*)data);
var ret = _changeCustomizeHook.Original(human, data, skipEquipment);
+
+ Glamourer.Log.Information($"[ChangeCustomize] Called on with {*(CustomizeArray*)data} ({ret}).");
_postEvent.Invoke(human);
return ret;
}
+
public void Subscribe(Action action, Post.Priority priority)
=> _postEvent.Subscribe(action, priority);
diff --git a/Glamourer/Interop/InventoryService.cs b/Glamourer/Interop/InventoryService.cs
index 6d8e58b..605ca15 100644
--- a/Glamourer/Interop/InventoryService.cs
+++ b/Glamourer/Interop/InventoryService.cs
@@ -1,9 +1,11 @@
using Dalamud.Hooking;
using Dalamud.Plugin.Services;
+using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
using Glamourer.Events;
using OtterGui.Services;
+using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.String;
@@ -16,39 +18,48 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
private readonly EquippedGearset _gearsetEvent;
private readonly List<(EquipSlot, uint, StainIds)> _itemList = new(12);
+ // This can be moved into client structs or penumbra.gamedata when needed.
+ public const string EquipGearsetInternal = "40 55 53 56 57 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 4C 63 FA";
+ private delegate nint ChangeGearsetInternalDelegate(RaptureGearsetModule* module, uint gearsetId, byte glamourPlateId);
+
+ [Signature(EquipGearsetInternal, DetourName = nameof(EquipGearSetInternalDetour))]
+ private readonly Hook _equipGearsetInternalHook = null!;
+
public InventoryService(MovedEquipment movedItemsEvent, IGameInteropProvider interop, EquippedGearset gearsetEvent)
{
_movedItemsEvent = movedItemsEvent;
_gearsetEvent = gearsetEvent;
_moveItemHook = interop.HookFromAddress((nint)InventoryManager.MemberFunctionPointers.MoveItemSlot, MoveItemDetour);
- _equipGearsetHook =
- interop.HookFromAddress((nint)RaptureGearsetModule.MemberFunctionPointers.EquipGearset, EquipGearSetDetour);
+ _equipGearsetHook = interop.HookFromAddress((nint)RaptureGearsetModule.MemberFunctionPointers.EquipGearset, EquipGearSetDetour);
+ interop.InitializeFromAttributes(this);
_moveItemHook.Enable();
_equipGearsetHook.Enable();
+ _equipGearsetInternalHook.Enable();
}
public void Dispose()
{
_moveItemHook.Dispose();
_equipGearsetHook.Dispose();
+ _equipGearsetInternalHook.Dispose();
}
private delegate int EquipGearsetDelegate(RaptureGearsetModule* module, int gearsetId, byte glamourPlateId);
private readonly Hook _equipGearsetHook;
- private int EquipGearSetDetour(RaptureGearsetModule* module, int gearsetId, byte glamourPlateId)
+ private nint EquipGearSetInternalDetour(RaptureGearsetModule* module, uint gearsetId, byte glamourPlateId)
{
var prior = module->CurrentGearsetIndex;
- var ret = _equipGearsetHook.Original(module, gearsetId, glamourPlateId);
- var set = module->GetGearset(gearsetId);
- _gearsetEvent.Invoke(new ByteString(set->Name).ToString(), gearsetId, prior, glamourPlateId, set->ClassJob);
- Glamourer.Log.Excessive($"[InventoryService] Applied gear set {gearsetId} with glamour plate {glamourPlateId} (Returned {ret})");
+ var ret = _equipGearsetInternalHook.Original(module, gearsetId, glamourPlateId);
+ var set = module->GetGearset((int)gearsetId);
+ _gearsetEvent.Invoke(new ByteString(set->Name).ToString(), (int)gearsetId, prior, glamourPlateId, set->ClassJob);
+ Glamourer.Log.Warning($"[InventoryService] [EquipInternal] Applied gear set {gearsetId} with glamour plate {glamourPlateId} (Returned {ret})");
if (ret == 0)
{
- var entry = module->GetGearset(gearsetId);
+ var entry = module->GetGearset((int)gearsetId);
if (entry == null)
return ret;
@@ -73,18 +84,18 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
}
var plate = MirageManager.Instance()->GlamourPlates[glamourPlateId - 1];
- Add(EquipSlot.MainHand, plate.ItemIds[0], StainIds.FromGlamourPlate(plate, 0), ref entry->Items[0]);
- Add(EquipSlot.OffHand, plate.ItemIds[1], StainIds.FromGlamourPlate(plate, 1), ref entry->Items[1]);
- Add(EquipSlot.Head, plate.ItemIds[2], StainIds.FromGlamourPlate(plate, 2), ref entry->Items[2]);
- Add(EquipSlot.Body, plate.ItemIds[3], StainIds.FromGlamourPlate(plate, 3), ref entry->Items[3]);
- Add(EquipSlot.Hands, plate.ItemIds[4], StainIds.FromGlamourPlate(plate, 4), ref entry->Items[5]);
- Add(EquipSlot.Legs, plate.ItemIds[5], StainIds.FromGlamourPlate(plate, 5), ref entry->Items[6]);
- Add(EquipSlot.Feet, plate.ItemIds[6], StainIds.FromGlamourPlate(plate, 6), ref entry->Items[7]);
- Add(EquipSlot.Ears, plate.ItemIds[7], StainIds.FromGlamourPlate(plate, 7), ref entry->Items[8]);
- Add(EquipSlot.Neck, plate.ItemIds[8], StainIds.FromGlamourPlate(plate, 8), ref entry->Items[9]);
- Add(EquipSlot.Wrists, plate.ItemIds[9], StainIds.FromGlamourPlate(plate, 9), ref entry->Items[10]);
- Add(EquipSlot.RFinger, plate.ItemIds[10], StainIds.FromGlamourPlate(plate, 10), ref entry->Items[11]);
- Add(EquipSlot.LFinger, plate.ItemIds[11], StainIds.FromGlamourPlate(plate, 11), ref entry->Items[12]);
+ Add(EquipSlot.MainHand, plate.ItemIds[0], StainIds.FromGlamourPlate(plate, 0), ref entry->Items[0]);
+ Add(EquipSlot.OffHand, plate.ItemIds[1], StainIds.FromGlamourPlate(plate, 1), ref entry->Items[1]);
+ Add(EquipSlot.Head, plate.ItemIds[2], StainIds.FromGlamourPlate(plate, 2), ref entry->Items[2]);
+ Add(EquipSlot.Body, plate.ItemIds[3], StainIds.FromGlamourPlate(plate, 3), ref entry->Items[3]);
+ Add(EquipSlot.Hands, plate.ItemIds[4], StainIds.FromGlamourPlate(plate, 4), ref entry->Items[5]);
+ Add(EquipSlot.Legs, plate.ItemIds[5], StainIds.FromGlamourPlate(plate, 5), ref entry->Items[6]);
+ Add(EquipSlot.Feet, plate.ItemIds[6], StainIds.FromGlamourPlate(plate, 6), ref entry->Items[7]);
+ Add(EquipSlot.Ears, plate.ItemIds[7], StainIds.FromGlamourPlate(plate, 7), ref entry->Items[8]);
+ Add(EquipSlot.Neck, plate.ItemIds[8], StainIds.FromGlamourPlate(plate, 8), ref entry->Items[9]);
+ Add(EquipSlot.Wrists, plate.ItemIds[9], StainIds.FromGlamourPlate(plate, 9), ref entry->Items[10]);
+ Add(EquipSlot.RFinger, plate.ItemIds[10], StainIds.FromGlamourPlate(plate, 10), ref entry->Items[11]);
+ Add(EquipSlot.LFinger, plate.ItemIds[11], StainIds.FromGlamourPlate(plate, 11), ref entry->Items[12]);
}
else
{
@@ -99,17 +110,17 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
}
Add(EquipSlot.MainHand, ref entry->Items[0]);
- Add(EquipSlot.OffHand, ref entry->Items[1]);
- Add(EquipSlot.Head, ref entry->Items[2]);
- Add(EquipSlot.Body, ref entry->Items[3]);
- Add(EquipSlot.Hands, ref entry->Items[5]);
- Add(EquipSlot.Legs, ref entry->Items[6]);
- Add(EquipSlot.Feet, ref entry->Items[7]);
- Add(EquipSlot.Ears, ref entry->Items[8]);
- Add(EquipSlot.Neck, ref entry->Items[9]);
- Add(EquipSlot.Wrists, ref entry->Items[10]);
- Add(EquipSlot.RFinger, ref entry->Items[11]);
- Add(EquipSlot.LFinger, ref entry->Items[12]);
+ Add(EquipSlot.OffHand, ref entry->Items[1]);
+ Add(EquipSlot.Head, ref entry->Items[2]);
+ Add(EquipSlot.Body, ref entry->Items[3]);
+ Add(EquipSlot.Hands, ref entry->Items[5]);
+ Add(EquipSlot.Legs, ref entry->Items[6]);
+ Add(EquipSlot.Feet, ref entry->Items[7]);
+ Add(EquipSlot.Ears, ref entry->Items[8]);
+ Add(EquipSlot.Neck, ref entry->Items[9]);
+ Add(EquipSlot.Wrists, ref entry->Items[10]);
+ Add(EquipSlot.RFinger, ref entry->Items[11]);
+ Add(EquipSlot.LFinger, ref entry->Items[12]);
}
_movedItemsEvent.Invoke(_itemList.ToArray());
@@ -118,6 +129,13 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
return ret;
}
+ private int EquipGearSetDetour(RaptureGearsetModule* module, int gearsetId, byte glamourPlateId)
+ {
+ var ret = _equipGearsetHook.Original(module, gearsetId, glamourPlateId);
+ Glamourer.Log.Verbose($"[InventoryService] Applied gear set {gearsetId} with glamour plate {glamourPlateId} (Returned {ret})");
+ return ret;
+ }
+
private static uint FixId(uint itemId)
=> itemId % 50000;
@@ -130,7 +148,7 @@ public sealed unsafe class InventoryService : IDisposable, IRequiredService
InventoryType targetContainer, ushort targetSlot, byte unk)
{
var ret = _moveItemHook.Original(manager, sourceContainer, sourceSlot, targetContainer, targetSlot, unk);
- Glamourer.Log.Excessive($"[InventoryService] Moved {sourceContainer} {sourceSlot} {targetContainer} {targetSlot} (Returned {ret})");
+ Glamourer.Log.Verbose($"[InventoryService] Moved {sourceContainer} {sourceSlot} {targetContainer} {targetSlot} (Returned {ret})");
if (ret == 0)
{
if (InvokeSource(sourceContainer, sourceSlot, out var source))
diff --git a/Glamourer/Interop/JobService.cs b/Glamourer/Interop/JobService.cs
index 1797809..f687715 100644
--- a/Glamourer/Interop/JobService.cs
+++ b/Glamourer/Interop/JobService.cs
@@ -50,7 +50,7 @@ public class JobService : IDisposable
var newJob = Jobs.TryGetValue(newJobIndex, out var j) ? j : Jobs[0];
var oldJob = Jobs.TryGetValue(oldJobIndex, out var o) ? o : Jobs[0];
- Glamourer.Log.Excessive($"{actor} changed job from {oldJob} to {newJob}.");
+ Glamourer.Log.Error($"{actor} changed job from {oldJob} to {newJob}.");
JobChanged?.Invoke(actor, oldJob, newJob);
}
}
diff --git a/Glamourer/Interop/UpdateSlotService.cs b/Glamourer/Interop/UpdateSlotService.cs
index d1004e6..e43dc74 100644
--- a/Glamourer/Interop/UpdateSlotService.cs
+++ b/Glamourer/Interop/UpdateSlotService.cs
@@ -1,36 +1,124 @@
using Dalamud.Hooking;
using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures;
+using FFXIVClientStructs.FFXIV.Client.Game.Character;
using Glamourer.Events;
using Penumbra.GameData;
using Penumbra.GameData.DataContainers;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Interop;
using Penumbra.GameData.Structs;
-
namespace Glamourer.Interop;
+///
+/// This struct is the struct that loadallequipment passes in as its gearsetData container.
+///
+[StructLayout(LayoutKind.Explicit)] // Size of 70 bytes maybe?
+public readonly struct GearsetItemDataStruct
+{
+ // Stores the weapon data. Includes both dyes in the data.
+ [FieldOffset(0)] public readonly WeaponModelId MainhandWeaponData;
+ [FieldOffset(8)] public readonly WeaponModelId OffhandWeaponData;
+
+ [FieldOffset(16)] public readonly byte CrestBitField; // A Bitfield:: ShieldCrest == 1, HeadCrest == 2, Chest Crest == 4
+ [FieldOffset(17)] public readonly byte JobId; // Job ID associated with the gearset change.
+
+ // Flicks from 0 to 128 (anywhere inbetween), have yet to associate what it is linked to. Remains the same when flicking between gearsets of the same job.
+ [FieldOffset(18)] public readonly byte UNK_18;
+ [FieldOffset(19)] public readonly byte UNK_19; // I have never seen this be anything other than 0.
+
+ // Legacy helmet equip slot armor for a character.
+ [FieldOffset(20)] public readonly LegacyCharacterArmor HeadSlotArmor;
+ [FieldOffset(24)] public readonly LegacyCharacterArmor TopSlotArmor;
+ [FieldOffset(28)] public readonly LegacyCharacterArmor ArmsSlotArmor;
+ [FieldOffset(32)] public readonly LegacyCharacterArmor LegsSlotArmor;
+ [FieldOffset(26)] public readonly LegacyCharacterArmor FeetSlotArmor;
+ [FieldOffset(40)] public readonly LegacyCharacterArmor EarSlotArmor;
+ [FieldOffset(44)] public readonly LegacyCharacterArmor NeckSlotArmor;
+ [FieldOffset(48)] public readonly LegacyCharacterArmor WristSlotArmor;
+ [FieldOffset(52)] public readonly LegacyCharacterArmor RFingerSlotArmor;
+ [FieldOffset(56)] public readonly LegacyCharacterArmor LFingerSlotArmor;
+
+ // Byte array of all slot's secondary dyes.
+ [FieldOffset(60)] public readonly byte HeadSlotSecondaryDye;
+ [FieldOffset(61)] public readonly byte TopSlotSecondaryDye;
+ [FieldOffset(62)] public readonly byte ArmsSlotSecondaryDye;
+ [FieldOffset(63)] public readonly byte LegsSlotSecondaryDye;
+ [FieldOffset(64)] public readonly byte FeetSlotSecondaryDye;
+ [FieldOffset(65)] public readonly byte EarSlotSecondaryDye;
+ [FieldOffset(66)] public readonly byte NeckSlotSecondaryDye;
+ [FieldOffset(67)] public readonly byte WristSlotSecondaryDye;
+ [FieldOffset(68)] public readonly byte RFingerSlotSecondaryDye;
+ [FieldOffset(69)] public readonly byte LFingerSlotSecondaryDye;
+}
+
public unsafe class UpdateSlotService : IDisposable
{
- public readonly EquipSlotUpdating EquipSlotUpdatingEvent;
- public readonly BonusSlotUpdating BonusSlotUpdatingEvent;
- private readonly DictBonusItems _bonusItems;
+ public readonly EquipSlotUpdating EquipSlotUpdatingEvent;
+ public readonly BonusSlotUpdating BonusSlotUpdatingEvent;
+ private readonly DictBonusItems _bonusItems;
+
+ #region LoadAllEquipData
+ ///////////////////////////////////////////////////
+ // This is a currently undocumented signature that loads all equipment after changing a gearset.
+ // :: Signature Maintainers Note:
+ // To obtain this signature, get the stacktrace from FlagSlotForUpdate for human, and find func `sub_140842F50`.
+ // This function is what calls the weapon/equipment/crest loads, which call FlagSlotForUpdate if different.
+ //
+ // By detouring this function, and executing the original, then logic after, we have a consistant point in time where we know all
+ // slots have been flagged, meaning a consistant point in time that glamourer has processed all of its updates.
+ public const string LoadAllEquipmentSig = "48 89 5C 24 ?? 55 56 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 44 0F B6 B9";
+ private delegate Int64 LoadAllEquipmentDelegate(DrawDataContainer* drawDataContainer, GearsetItemDataStruct* gearsetData);
+ private Int64 LoadAllEquipmentDetour(DrawDataContainer* drawDataContainer, GearsetItemDataStruct* gearsetData)
+ {
+ // return original first so we can log the changes after
+ var ret = _loadAllEquipmentHook.Original(drawDataContainer, gearsetData);
+
+ // perform logic stuff.
+ var owner = drawDataContainer->OwnerObject;
+ Glamourer.Log.Warning($"[LoadAllEquipmentDetour] Owner: 0x{(nint)owner->DrawObject:X} Finished Applying its GameState!");
+ Glamourer.Log.Warning($"[LoadAllEquipmentDetour] GearsetItemData: {FormatGearsetItemDataStruct(*gearsetData)}");
+
+ // return original.
+ return ret;
+ }
+
+ private string FormatWeaponModelId(WeaponModelId weaponModelId) => $"Id: {weaponModelId.Id}, Type: {weaponModelId.Type}, Variant: {weaponModelId.Variant}, Stain0: {weaponModelId.Stain0}, Stain1: {weaponModelId.Stain1}";
+
+ private string FormatGearsetItemDataStruct(GearsetItemDataStruct gearsetItemData)
+ {
+ string ret = $"\nMainhandWeaponData: {FormatWeaponModelId(gearsetItemData.MainhandWeaponData)}," +
+ $"\nOffhandWeaponData: {FormatWeaponModelId(gearsetItemData.OffhandWeaponData)}," +
+ $"\nCrestBitField: {gearsetItemData.CrestBitField} | JobId: {gearsetItemData.JobId} | UNK_18: {gearsetItemData.UNK_18} | UNK_19: {gearsetItemData.UNK_19}";
+ // Iterate through offsets from 20 to 60 and format the CharacterArmor data
+ for (int offset = 20; offset <= 56; offset += sizeof(LegacyCharacterArmor))
+ {
+ LegacyCharacterArmor* equipSlotPtr = (LegacyCharacterArmor*)((byte*)&gearsetItemData + offset);
+ int dyeOffset = (offset - 20) / sizeof(LegacyCharacterArmor) + 60; // Calculate the corresponding dye offset
+ byte* dyePtr = (byte*)&gearsetItemData + dyeOffset;
+ ret += $"\nEquipSlot {((EquipSlot)(dyeOffset-60)).ToString()}:: Id: {(*equipSlotPtr).Set}, Variant: {(*equipSlotPtr).Variant}, Stain0: {(*equipSlotPtr).Stain.Id}, Stain1: {*dyePtr}";
+ }
+ return ret;
+ }
+#endregion LoadAllEquipData
public UpdateSlotService(EquipSlotUpdating equipSlotUpdating, BonusSlotUpdating bonusSlotUpdating, IGameInteropProvider interop,
DictBonusItems bonusItems)
{
EquipSlotUpdatingEvent = equipSlotUpdating;
BonusSlotUpdatingEvent = bonusSlotUpdating;
- _bonusItems = bonusItems;
+ _bonusItems = bonusItems;
interop.InitializeFromAttributes(this);
_flagSlotForUpdateHook.Enable();
_flagBonusSlotForUpdateHook.Enable();
+ _loadAllEquipmentHook.Enable();
}
public void Dispose()
{
_flagSlotForUpdateHook.Dispose();
_flagBonusSlotForUpdateHook.Dispose();
+ _loadAllEquipmentHook.Dispose();
}
public void UpdateEquipSlot(Model drawObject, EquipSlot slot, CharacterArmor data)
@@ -79,24 +167,36 @@ public unsafe class UpdateSlotService : IDisposable
[Signature(Sigs.FlagBonusSlotForUpdate, DetourName = nameof(FlagBonusSlotForUpdateDetour))]
private readonly Hook _flagBonusSlotForUpdateHook = null!;
+ [Signature(LoadAllEquipmentSig, DetourName = nameof(LoadAllEquipmentDetour))]
+ private readonly Hook _loadAllEquipmentHook = null!;
+
private ulong FlagSlotForUpdateDetour(nint drawObject, uint slotIdx, CharacterArmor* data)
{
- var slot = slotIdx.ToEquipSlot();
+ var slot = slotIdx.ToEquipSlot();
var returnValue = ulong.MaxValue;
+
EquipSlotUpdatingEvent.Invoke(drawObject, slot, ref *data, ref returnValue);
- Glamourer.Log.Excessive($"[FlagSlotForUpdate] Called with 0x{drawObject:X} for slot {slot} with {*data} ({returnValue:X}).");
- return returnValue == ulong.MaxValue ? _flagSlotForUpdateHook.Original(drawObject, slotIdx, data) : returnValue;
+ Glamourer.Log.Information($"[FlagSlotForUpdate] Called with 0x{drawObject:X} for slot {slot} with {*data} ({returnValue:X}).");
+ returnValue = returnValue == ulong.MaxValue ? _flagSlotForUpdateHook.Original(drawObject, slotIdx, data) : returnValue;
+
+ return returnValue;
}
private ulong FlagBonusSlotForUpdateDetour(nint drawObject, uint slotIdx, CharacterArmor* data)
{
- var slot = slotIdx.ToBonusSlot();
+ var slot = slotIdx.ToBonusSlot();
var returnValue = ulong.MaxValue;
+
BonusSlotUpdatingEvent.Invoke(drawObject, slot, ref *data, ref returnValue);
- Glamourer.Log.Excessive($"[FlagBonusSlotForUpdate] Called with 0x{drawObject:X} for slot {slot} with {*data} ({returnValue:X}).");
- return returnValue == ulong.MaxValue ? _flagBonusSlotForUpdateHook.Original(drawObject, slotIdx, data) : returnValue;
+ Glamourer.Log.Information($"[FlagBonusSlotForUpdate] Called with 0x{drawObject:X} for slot {slot} with {*data} ({returnValue:X}).");
+ returnValue = returnValue == ulong.MaxValue ? _flagBonusSlotForUpdateHook.Original(drawObject, slotIdx, data) : returnValue;
+
+ return returnValue;
}
private ulong FlagSlotForUpdateInterop(Model drawObject, EquipSlot slot, CharacterArmor armor)
- => _flagSlotForUpdateHook.Original(drawObject.Address, slot.ToIndex(), &armor);
+ {
+ Glamourer.Log.Warning($"Glamour-Invoked Equip Slot update for 0x{drawObject.Address:X} with {slot} and {armor}.");
+ return _flagSlotForUpdateHook.Original(drawObject.Address, slot.ToIndex(), &armor);
+ }
}
diff --git a/Glamourer/State/StateEditor.cs b/Glamourer/State/StateEditor.cs
index f9ddb89..b592b65 100644
--- a/Glamourer/State/StateEditor.cs
+++ b/Glamourer/State/StateEditor.cs
@@ -51,7 +51,7 @@ public class StateEditor(
return;
var actors = Applier.ChangeCustomize(state, settings.Source.RequiresChange());
- Glamourer.Log.Verbose(
+ Glamourer.Log.Information(
$"Set {idx.ToDefaultName()} customizations in state {state.Identifier.Incognito(null)} from {old.Value} to {value.Value}. [Affecting {actors.ToLazyString("nothing")}.]");
StateChanged.Invoke(StateChangeType.Customize, settings.Source, state, actors, new CustomizeTransaction(idx, old, value));
}
@@ -64,7 +64,7 @@ public class StateEditor(
return;
var actors = Applier.ChangeCustomize(state, settings.Source.RequiresChange());
- Glamourer.Log.Verbose(
+ Glamourer.Log.Information(
$"Set {applied} customizations in state {state.Identifier.Incognito(null)} from {old} to {customizeInput}. [Affecting {actors.ToLazyString("nothing")}.]");
StateChanged.Invoke(StateChangeType.EntireCustomize, settings.Source, state, actors,
new EntireCustomizeTransaction(applied, old, customizeInput));
@@ -75,7 +75,10 @@ public class StateEditor(
{
var state = (ActorState)data;
if (!Editor.ChangeItem(state, slot, item, settings.Source, out var old, settings.Key))
+ {
+ Glamourer.Log.Information("Not Setting State or invoking, Editor requested us not to change it!");
return;
+ }
var type = slot.ToIndex() < 10 ? StateChangeType.Equip : StateChangeType.Weapon;
var actors = type is StateChangeType.Equip
@@ -86,8 +89,8 @@ public class StateEditor(
if (slot is EquipSlot.MainHand)
ApplyMainhandPeriphery(state, item, null, settings);
- Glamourer.Log.Verbose(
- $"Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item.Name} ({item.ItemId}). [Affecting {actors.ToLazyString("nothing")}.]");
+ Glamourer.Log.Debug(
+ $"[ChangeItem] Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item.Name} ({item.ItemId}). [Affecting {actors.ToLazyString("nothing")}.]");
if (type is StateChangeType.Equip)
{
@@ -116,8 +119,8 @@ public class StateEditor(
return;
var actors = Applier.ChangeBonusItem(state, slot, settings.Source.RequiresChange());
- Glamourer.Log.Verbose(
- $"Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.Id}) to {item.Name} ({item.Id}). [Affecting {actors.ToLazyString("nothing")}.]");
+ Glamourer.Log.Debug(
+ $"[ChangeBonus] Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.Id}) to {item.Name} ({item.Id}). [Affecting {actors.ToLazyString("nothing")}.]");
StateChanged.Invoke(StateChangeType.BonusItem, settings.Source, state, actors, new BonusItemTransaction(slot, old, item));
}
@@ -149,8 +152,8 @@ public class StateEditor(
if (slot is EquipSlot.MainHand)
ApplyMainhandPeriphery(state, item, stains, settings);
- Glamourer.Log.Verbose(
- $"Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item!.Value.Name} ({item.Value.ItemId}) and its stain from {oldStains} to {stains!.Value}. [Affecting {actors.ToLazyString("nothing")}.]");
+ Glamourer.Log.Debug(
+ $"[ChangeEquip] Set {slot.ToName()} in state {state.Identifier.Incognito(null)} from {old.Name} ({old.ItemId}) to {item!.Value.Name} ({item.Value.ItemId}) and its stain from {oldStains} to {stains!.Value}. [Affecting {actors.ToLazyString("nothing")}.]");
if (type is StateChangeType.Equip)
{
StateChanged.Invoke(type, settings.Source, state, actors, new EquipTransaction(slot, old, item!.Value));
@@ -181,7 +184,7 @@ public class StateEditor(
return;
var actors = Applier.ChangeStain(state, slot, settings.Source.RequiresChange());
- Glamourer.Log.Verbose(
+ Glamourer.Log.Debug(
$"Set {slot.ToName()} stain in state {state.Identifier.Incognito(null)} from {old} to {stains}. [Affecting {actors.ToLazyString("nothing")}.]");
StateChanged.Invoke(StateChangeType.Stains, settings.Source, state, actors, new StainTransaction(slot, old, stains));
}
@@ -250,7 +253,7 @@ public class StateEditor(
return;
var actors = Applier.ChangeMetaState(state, index, settings.Source.RequiresChange());
- Glamourer.Log.Verbose(
+ Glamourer.Log.Debug(
$"Set {index.ToName()} in state {state.Identifier.Incognito(null)} from {old} to {value}. [Affecting {actors.ToLazyString("nothing")}.]");
StateChanged.Invoke(StateChangeType.Other, settings.Source, state, actors, new MetaTransaction(index, old, value));
}
@@ -414,8 +417,7 @@ public class StateEditor(
? Applier.ApplyAll(state, requiresRedraw, false)
: ActorData.Invalid;
- Glamourer.Log.Verbose(
- $"Applied design to {state.Identifier.Incognito(null)}. [Affecting {actors.ToLazyString("nothing")}.]");
+ Glamourer.Log.Debug($"Applied design to {state.Identifier.Incognito(null)}. [Affecting {actors.ToLazyString("nothing")}.]");
StateChanged.Invoke(StateChangeType.Design, state.Sources[MetaIndex.Wetness], state, actors, null); // FIXME: maybe later
return;
diff --git a/Glamourer/State/StateListener.cs b/Glamourer/State/StateListener.cs
index d054a25..382e488 100644
--- a/Glamourer/State/StateListener.cs
+++ b/Glamourer/State/StateListener.cs
@@ -216,8 +216,7 @@ public class StateListener : IDisposable
// then we do not want to use our restricted gear protection
// since we assume the player has that gear modded to availability.
var locked = false;
- if (actor.Identifier(_actors, out var identifier)
- && _manager.TryGetValue(identifier, out var state))
+ if (actor.Identifier(_actors, out var identifier) && _manager.TryGetValue(identifier, out var state))
{
HandleEquipSlot(actor, state, slot, ref armor);
locked = state.Sources[slot, false] is StateSource.IpcFixed;
@@ -383,7 +382,7 @@ public class StateListener : IDisposable
lastFistOffhand = new CharacterWeapon((PrimaryId)(weapon.Skeleton.Id + 50), weapon.Weapon, weapon.Variant,
weapon.Stains);
_fistOffhands[actor] = lastFistOffhand;
- Glamourer.Log.Excessive($"Storing fist weapon offhand {lastFistOffhand} for 0x{actor.Address:X}.");
+ Glamourer.Log.Verbose($"Storing fist weapon offhand {lastFistOffhand} for 0x{actor.Address:X}.");
}
_funModule.ApplyFunToWeapon(actor, ref weapon, slot);
diff --git a/Glamourer/State/StateManager.cs b/Glamourer/State/StateManager.cs
index eabaf2f..736dd6e 100644
--- a/Glamourer/State/StateManager.cs
+++ b/Glamourer/State/StateManager.cs
@@ -273,7 +273,7 @@ public sealed class StateManager(
if (source is not StateSource.Game)
actors = Applier.ApplyAll(state, redraw, true);
- Glamourer.Log.Verbose(
+ Glamourer.Log.Debug(
$"Reset entire state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
StateChanged.Invoke(StateChangeType.Reset, source, state, actors, null);
}
@@ -298,7 +298,7 @@ public sealed class StateManager(
state.Materials.Clear();
- Glamourer.Log.Verbose(
+ Glamourer.Log.Debug(
$"Reset advanced customization and dye state of {state.Identifier.Incognito(null)} to game base. [Affecting {actors.ToLazyString("nothing")}.]");
StateChanged.Invoke(StateChangeType.Reset, source, state, actors, null);
}