mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Update for 6.4, 0.1.2.0
This commit is contained in:
parent
956e1fc1a7
commit
f97829ab7f
8 changed files with 187 additions and 200 deletions
|
|
@ -1,83 +1,86 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.PlayerWatch;
|
||||
|
||||
namespace Glamourer
|
||||
namespace Glamourer;
|
||||
|
||||
public static class WriteExtensions
|
||||
{
|
||||
public static class WriteExtensions
|
||||
{
|
||||
private static unsafe void Write(IntPtr characterPtr, EquipSlot slot, SetId? id, WeaponType? type, ushort? variant, StainId? stain)
|
||||
{
|
||||
void WriteWeapon(int offset)
|
||||
{
|
||||
var address = (byte*) characterPtr + offset;
|
||||
var address = (byte*)characterPtr + offset;
|
||||
if (id.HasValue)
|
||||
*(ushort*) address = (ushort) id.Value;
|
||||
*(ushort*)address = (ushort)id.Value;
|
||||
|
||||
if (type.HasValue)
|
||||
*(ushort*) (address + 2) = (ushort) type.Value;
|
||||
*(ushort*)(address + 2) = (ushort)type.Value;
|
||||
|
||||
if (variant.HasValue)
|
||||
*(ushort*) (address + 4) = variant.Value;
|
||||
*(ushort*)(address + 4) = variant.Value;
|
||||
|
||||
if (*(ushort*) address == 0)
|
||||
if (*(ushort*)address == 0)
|
||||
*(address + 6) = 0;
|
||||
else if (stain.HasValue)
|
||||
*(address + 6) = (byte) stain.Value;
|
||||
*(address + 6) = (byte)stain.Value;
|
||||
}
|
||||
|
||||
void WriteEquip(int offset)
|
||||
{
|
||||
var address = (byte*) characterPtr + offset;
|
||||
var address = (byte*)characterPtr + offset;
|
||||
if (id.HasValue)
|
||||
*(ushort*) address = (ushort) id.Value;
|
||||
*(ushort*)address = (ushort)id.Value;
|
||||
|
||||
if (variant < byte.MaxValue)
|
||||
*(address + 2) = (byte) variant.Value;
|
||||
*(address + 2) = (byte)variant.Value;
|
||||
|
||||
if (stain.HasValue)
|
||||
*(address + 3) = (byte) stain.Value;
|
||||
*(address + 3) = (byte)stain.Value;
|
||||
}
|
||||
|
||||
var drawDataOffset = (int) Marshal.OffsetOf<Character>(nameof(Character.DrawData));
|
||||
switch (slot)
|
||||
{
|
||||
case EquipSlot.MainHand:
|
||||
WriteWeapon(CharacterEquipment.MainWeaponOffset);
|
||||
WriteWeapon(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.MainHandModel)));
|
||||
break;
|
||||
case EquipSlot.OffHand:
|
||||
WriteWeapon(CharacterEquipment.OffWeaponOffset);
|
||||
WriteWeapon(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.OffHandModel)));
|
||||
break;
|
||||
case EquipSlot.Head:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Head)));
|
||||
break;
|
||||
case EquipSlot.Body:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 4);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Top)));
|
||||
break;
|
||||
case EquipSlot.Hands:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 8);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Arms)));
|
||||
break;
|
||||
case EquipSlot.Legs:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 12);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Legs)));
|
||||
break;
|
||||
case EquipSlot.Feet:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 16);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Feet)));
|
||||
break;
|
||||
case EquipSlot.Ears:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 20);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Ear)));
|
||||
break;
|
||||
case EquipSlot.Neck:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 24);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Neck)));
|
||||
break;
|
||||
case EquipSlot.Wrists:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 28);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Wrist)));
|
||||
break;
|
||||
case EquipSlot.RFinger:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 32);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.RFinger)));
|
||||
break;
|
||||
case EquipSlot.LFinger:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 36);
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.LFinger)));
|
||||
break;
|
||||
default: throw new InvalidEnumArgumentException();
|
||||
}
|
||||
|
|
@ -113,7 +116,7 @@ namespace Glamourer
|
|||
|
||||
fixed (CharacterArmor* equipment = &equip.Head)
|
||||
{
|
||||
Buffer.MemoryCopy(equipment, (byte*) characterAddress + CharacterEquipment.EquipmentOffset,
|
||||
Buffer.MemoryCopy(equipment, &((Character*)characterAddress)->DrawData.Head,
|
||||
CharacterEquipment.EquipmentSlots * sizeof(CharacterArmor), CharacterEquipment.EquipmentSlots * sizeof(CharacterArmor));
|
||||
}
|
||||
}
|
||||
|
|
@ -177,5 +180,4 @@ namespace Glamourer
|
|||
if (stains.HasFlag(CharacterEquipMask.RFinger))
|
||||
Write(characterAddress, EquipSlot.RFinger, null, null, null, equip.RFinger.Stain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,13 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Character = Dalamud.Game.ClientState.Objects.Types.Character;
|
||||
|
||||
namespace Glamourer.Customization
|
||||
{
|
||||
public unsafe struct LazyCustomization
|
||||
{
|
||||
public CharacterCustomization* Address;
|
||||
|
||||
public LazyCustomization(IntPtr characterPtr)
|
||||
=> Address = (CharacterCustomization*) (characterPtr + CharacterCustomization.CustomizationOffset);
|
||||
|
||||
public ref CharacterCustomization Value
|
||||
=> ref *Address;
|
||||
|
||||
public LazyCustomization(CharacterCustomization data)
|
||||
=> Address = &data;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct CharacterCustomization
|
||||
{
|
||||
public const int CustomizationOffset = 0x840;
|
||||
public const int CustomizationBytes = 26;
|
||||
|
||||
public static CharacterCustomization Default = new()
|
||||
|
|
@ -150,13 +134,13 @@ namespace Glamourer.Customization
|
|||
}
|
||||
}
|
||||
|
||||
public void Read(Character character)
|
||||
=> Read(character.Address + CustomizationOffset);
|
||||
public unsafe void Read(Character character)
|
||||
=> Read((nint) ((FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)character.Address)->DrawData.CustomizeData.Data);
|
||||
|
||||
public CharacterCustomization(Character character)
|
||||
: this()
|
||||
{
|
||||
Read(character.Address + CustomizationOffset);
|
||||
Read(character);
|
||||
}
|
||||
|
||||
public byte this[CustomizationId id]
|
||||
|
|
@ -282,7 +266,7 @@ namespace Glamourer.Customization
|
|||
{
|
||||
fixed (Race* ptr = &Race)
|
||||
{
|
||||
Buffer.MemoryCopy(ptr, (byte*) characterAddress + CustomizationOffset, CustomizationBytes, CustomizationBytes);
|
||||
Buffer.MemoryCopy(ptr, ((FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)characterAddress)->DrawData.CustomizeData.Data, CustomizationBytes, CustomizationBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
<PlatformTarget>x64</PlatformTarget>
|
||||
<RootNamespace>Glamourer</RootNamespace>
|
||||
<AssemblyName>Glamourer</AssemblyName>
|
||||
<FileVersion>0.1.1.5</FileVersion>
|
||||
<AssemblyVersion>0.1.1.5</AssemblyVersion>
|
||||
<FileVersion>0.1.2.0</FileVersion>
|
||||
<AssemblyVersion>0.1.2.0</AssemblyVersion>
|
||||
<Company>SoftOtter</Company>
|
||||
<Product>Glamourer</Product>
|
||||
<Copyright>Copyright © 2020</Copyright>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"Description": "Adds functionality to change and store appearance of players, customization and equip. Requires Penumbra to be installed and activated to work. Can also add preview options to the Changed Items tab for Penumbra.",
|
||||
"Tags": [ "Appearance", "Glamour", "Race", "Outfit", "Armor", "Clothes", "Skins", "Customization", "Design", "Character" ],
|
||||
"InternalName": "Glamourer",
|
||||
"AssemblyVersion": "0.1.1.5",
|
||||
"AssemblyVersion": "0.1.2.0",
|
||||
"RepoUrl": "https://github.com/Ottermandias/Glamourer",
|
||||
"ApplicableVersion": "any",
|
||||
"DalamudApiLevel": 8,
|
||||
|
|
|
|||
|
|
@ -4,18 +4,18 @@ public static class Offsets
|
|||
{
|
||||
public static class Character
|
||||
{
|
||||
public const int Wetness = 0x1B1F;
|
||||
public const int HatVisible = 0x85E;
|
||||
public const int VisorToggled = 0x85F;
|
||||
public const int WeaponHidden1 = 0x85F;
|
||||
public const int WeaponHidden2 = 0x73C;
|
||||
public const int Alpha = 0x1A18;
|
||||
public const int Wetness = 0x1B3A;
|
||||
public const int HatVisible = 0x876;
|
||||
public const int VisorToggled = 0x877;
|
||||
public const int WeaponHidden1 = 0x877;
|
||||
public const int WeaponHidden2 = 0x754;
|
||||
public const int Alpha = 0x1A4C;
|
||||
|
||||
public static class Flags
|
||||
{
|
||||
public const byte IsHatHidden = 0x01;
|
||||
public const byte IsVisorToggled = 0x08;
|
||||
public const byte IsWet = 0x40;
|
||||
public const byte IsWet = 0x20;
|
||||
public const byte IsWeaponHidden1 = 0x01;
|
||||
public const byte IsWeaponHidden2 = 0x02;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ namespace Penumbra.PlayerWatch;
|
|||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class CharacterEquipment
|
||||
{
|
||||
public const int MainWeaponOffset = 0x6E0;
|
||||
public const int OffWeaponOffset = 0x748;
|
||||
public const int EquipmentOffset = 0x818;
|
||||
public const int EquipmentSlots = 10;
|
||||
public const int WeaponSlots = 2;
|
||||
|
||||
|
|
@ -58,16 +55,16 @@ public class CharacterEquipment
|
|||
private unsafe CharacterEquipment(IntPtr actorAddress)
|
||||
{
|
||||
IsSet = 1;
|
||||
var actorPtr = (byte*)actorAddress.ToPointer();
|
||||
var actorPtr = (FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)actorAddress.ToPointer();
|
||||
fixed (CharacterWeapon* main = &MainHand, off = &OffHand)
|
||||
{
|
||||
Buffer.MemoryCopy(actorPtr + MainWeaponOffset, main, sizeof(CharacterWeapon), sizeof(CharacterWeapon));
|
||||
Buffer.MemoryCopy(actorPtr + OffWeaponOffset, off, sizeof(CharacterWeapon), sizeof(CharacterWeapon));
|
||||
Buffer.MemoryCopy(&actorPtr->DrawData.MainHandModel, main, sizeof(CharacterWeapon), sizeof(CharacterWeapon));
|
||||
Buffer.MemoryCopy(&actorPtr->DrawData.OffHandModel, off, sizeof(CharacterWeapon), sizeof(CharacterWeapon));
|
||||
}
|
||||
|
||||
fixed (CharacterArmor* equipment = &Head)
|
||||
{
|
||||
Buffer.MemoryCopy(actorPtr + EquipmentOffset, equipment, EquipmentSlots * sizeof(CharacterArmor),
|
||||
Buffer.MemoryCopy(&actorPtr->DrawData.Head, equipment, EquipmentSlots * sizeof(CharacterArmor),
|
||||
EquipmentSlots * sizeof(CharacterArmor));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@
|
|||
<HintPath>$(DalamudLibPath)Dalamud.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="FFXIVClientStructs">
|
||||
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
"Description": "Adds functionality to change and store appearance of players, customization and equip. Requires Penumbra to be installed and activated to work. Can also add preview options to the Changed Items tab for Penumbra.",
|
||||
"Tags": [ "Appearance", "Glamour", "Race", "Outfit", "Armor", "Clothes", "Skins", "Customization", "Design", "Character" ],
|
||||
"InternalName": "Glamourer",
|
||||
"AssemblyVersion": "0.1.1.5",
|
||||
"TestingAssemblyVersion": "0.1.1.5",
|
||||
"AssemblyVersion": "0.1.2.0",
|
||||
"TestingAssemblyVersion": "0.1.2.0",
|
||||
"RepoUrl": "https://github.com/Ottermandias/Glamourer",
|
||||
"ApplicableVersion": "any",
|
||||
"DalamudApiLevel": 8,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue