mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 10:17:23 +01:00
Introduce CharacterSave and rudimentary Clipboard buttons.
This commit is contained in:
parent
d582c83152
commit
f71b800b2e
3 changed files with 137 additions and 11 deletions
|
|
@ -250,14 +250,18 @@ namespace Glamourer.Customization
|
|||
}
|
||||
}
|
||||
|
||||
public unsafe byte[] ToBytes()
|
||||
public unsafe void WriteBytes(byte[] array, int offset = 0)
|
||||
{
|
||||
var ret = new byte[CustomizationBytes];
|
||||
fixed (byte* ptr = &_race)
|
||||
{
|
||||
Marshal.Copy(new IntPtr(ptr), ret, 0, CustomizationBytes);
|
||||
Marshal.Copy(new IntPtr(ptr), array, offset, CustomizationBytes);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] ToBytes()
|
||||
{
|
||||
var ret = new byte[CustomizationBytes];
|
||||
WriteBytes(ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using Dalamud.Game.ClientState.Actors;
|
||||
using Dalamud.Game.ClientState.Actors.Types;
|
||||
using Dalamud.Interface;
|
||||
|
|
@ -735,9 +736,8 @@ namespace Glamourer.Gui
|
|||
|
||||
private static readonly CustomizationId[] AllCustomizations = (CustomizationId[]) Enum.GetValues(typeof(CustomizationId));
|
||||
|
||||
private bool DrawStuff()
|
||||
private bool DrawStuff(LazyCustomization x)
|
||||
{
|
||||
var x = new LazyCustomization(_player!.Address);
|
||||
_currentSubRace = x.Value.Clan;
|
||||
_currentGender = x.Value.Gender;
|
||||
var ret = DrawGenderSelector(x);
|
||||
|
|
@ -885,8 +885,37 @@ namespace Glamourer.Gui
|
|||
changes |= DrawEquip(EquipSlot.LFinger, equip.LFinger);
|
||||
}
|
||||
|
||||
var x = new LazyCustomization(_player!.Address);
|
||||
if (ImGui.CollapsingHeader("Character Customization"))
|
||||
changes |= DrawStuff();
|
||||
changes |= DrawStuff(x);
|
||||
|
||||
if (ImGui.Button("Copy to Clipboard"))
|
||||
{
|
||||
var save = new CharacterSave();
|
||||
save.Load(x.Value);
|
||||
save.Load(equip);
|
||||
Clipboard.SetText(save.ToBase64());
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Apply from Clipboard"))
|
||||
{
|
||||
var text = Clipboard.GetText();
|
||||
if (text.Any())
|
||||
{
|
||||
try
|
||||
{
|
||||
var save = CharacterSave.FromString(text);
|
||||
save.Customizations.Write(_player.Address);
|
||||
save.Equipment.Write(_player.Address);
|
||||
changes = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
PluginLog.Information($"{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changes)
|
||||
UpdateActors(_player);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Plugin;
|
||||
using Glamourer.Customization;
|
||||
|
|
@ -15,12 +17,103 @@ namespace Glamourer
|
|||
{
|
||||
public class CharacterSave
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public ActorCustomization Customizations { get; private set; }
|
||||
public ActorEquipment Equipment { get; private set; } = null!;
|
||||
public const byte CurrentVersion = 1;
|
||||
public const byte TotalSizeVersion1 = 1 + 1 + 2 + 56 + ActorCustomization.CustomizationBytes;
|
||||
|
||||
public ActorEquipMask WriteEquipment { get; set; } = ActorEquipMask.None;
|
||||
public bool WriteCustomizations { get; set; } = false;
|
||||
public const byte TotalSize = TotalSizeVersion1;
|
||||
|
||||
private readonly byte[] _bytes = new byte[TotalSize];
|
||||
|
||||
public CharacterSave()
|
||||
=> _bytes[0] = CurrentVersion;
|
||||
|
||||
public byte Version
|
||||
=> _bytes[0];
|
||||
|
||||
public bool WriteCustomizations
|
||||
{
|
||||
get => _bytes[1] != 0;
|
||||
set => _bytes[1] = (byte) (value ? 1 : 0);
|
||||
}
|
||||
|
||||
public ActorEquipMask WriteEquipment
|
||||
{
|
||||
get => (ActorEquipMask) ((ushort) _bytes[2] | ((ushort) _bytes[3] << 8));
|
||||
set
|
||||
{
|
||||
_bytes[2] = (byte) (((ushort) value) & 0xFF);
|
||||
_bytes[3] = (byte) (((ushort) value) >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
public void Load(ActorCustomization customization)
|
||||
{
|
||||
WriteCustomizations = true;
|
||||
customization.WriteBytes(_bytes, 4);
|
||||
}
|
||||
|
||||
public void Load(ActorEquipment equipment, ActorEquipMask mask = ActorEquipMask.All)
|
||||
{
|
||||
WriteEquipment = mask;
|
||||
equipment.WriteBytes(_bytes, 4 + ActorCustomization.CustomizationBytes);
|
||||
}
|
||||
|
||||
public string ToBase64()
|
||||
=> System.Convert.ToBase64String(_bytes);
|
||||
|
||||
public void Load(string base64)
|
||||
{
|
||||
var bytes = System.Convert.FromBase64String(base64);
|
||||
switch (bytes[0])
|
||||
{
|
||||
case 1:
|
||||
if (bytes.Length != TotalSizeVersion1)
|
||||
throw new Exception(
|
||||
$"Can not parse Base64 string into CharacterSave:\n\tInvalid size {bytes.Length} instead of {TotalSizeVersion1}.");
|
||||
if (bytes[1] != 0 && bytes[1] != 1)
|
||||
throw new Exception(
|
||||
$"Can not parse Base64 string into CharacterSave:\n\tInvalid value {bytes[1]} in byte 2, should be either 0 or 1.");
|
||||
|
||||
var mask = (ActorEquipMask) ((ushort) bytes[2] | ((ushort) bytes[3] << 8));
|
||||
if (!Enum.IsDefined(typeof(ActorEquipMask), mask))
|
||||
throw new Exception($"Can not parse Base64 string into CharacterSave:\n\tInvalid value {mask} in byte 3 and 4.");
|
||||
bytes.CopyTo(_bytes, 0);
|
||||
break;
|
||||
default:
|
||||
throw new Exception($"Can not parse Base64 string into CharacterSave:\n\tInvalid Version {bytes[0]}.");
|
||||
}
|
||||
}
|
||||
|
||||
public static CharacterSave FromString(string base64)
|
||||
{
|
||||
var ret = new CharacterSave();
|
||||
ret.Load(base64);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public unsafe ActorCustomization Customizations
|
||||
{
|
||||
get
|
||||
{
|
||||
var ret = new ActorCustomization();
|
||||
fixed (byte* ptr = _bytes)
|
||||
{
|
||||
ret.Read(new IntPtr(ptr) + 4);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ActorEquipment Equipment
|
||||
{
|
||||
get
|
||||
{
|
||||
var ret = new ActorEquipment();
|
||||
ret.FromBytes(_bytes, 4 + ActorCustomization.CustomizationBytes);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class Glamourer
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue