mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +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)
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Windows.Forms;
|
||||||
using Dalamud.Game.ClientState.Actors;
|
using Dalamud.Game.ClientState.Actors;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Actors.Types;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
|
|
@ -735,9 +736,8 @@ namespace Glamourer.Gui
|
||||||
|
|
||||||
private static readonly CustomizationId[] AllCustomizations = (CustomizationId[]) Enum.GetValues(typeof(CustomizationId));
|
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;
|
_currentSubRace = x.Value.Clan;
|
||||||
_currentGender = x.Value.Gender;
|
_currentGender = x.Value.Gender;
|
||||||
var ret = DrawGenderSelector(x);
|
var ret = DrawGenderSelector(x);
|
||||||
|
|
@ -885,8 +885,37 @@ namespace Glamourer.Gui
|
||||||
changes |= DrawEquip(EquipSlot.LFinger, equip.LFinger);
|
changes |= DrawEquip(EquipSlot.LFinger, equip.LFinger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var x = new LazyCustomization(_player!.Address);
|
||||||
if (ImGui.CollapsingHeader("Character Customization"))
|
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)
|
if (changes)
|
||||||
UpdateActors(_player);
|
UpdateActors(_player);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Cryptography;
|
||||||
using Dalamud.Game.Command;
|
using Dalamud.Game.Command;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Glamourer.Customization;
|
using Glamourer.Customization;
|
||||||
|
|
@ -15,12 +17,103 @@ namespace Glamourer
|
||||||
{
|
{
|
||||||
public class CharacterSave
|
public class CharacterSave
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = string.Empty;
|
public const byte CurrentVersion = 1;
|
||||||
public ActorCustomization Customizations { get; private set; }
|
public const byte TotalSizeVersion1 = 1 + 1 + 2 + 56 + ActorCustomization.CustomizationBytes;
|
||||||
public ActorEquipment Equipment { get; private set; } = null!;
|
|
||||||
|
|
||||||
public ActorEquipMask WriteEquipment { get; set; } = ActorEquipMask.None;
|
public const byte TotalSize = TotalSizeVersion1;
|
||||||
public bool WriteCustomizations { get; set; } = false;
|
|
||||||
|
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
|
internal class Glamourer
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue