Add support for Palette+ (#40)
This commit is contained in:
@@ -11,6 +11,7 @@ public record MareCharaFileData
|
|||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; } = string.Empty;
|
||||||
public string GlamourerData { get; set; } = string.Empty;
|
public string GlamourerData { get; set; } = string.Empty;
|
||||||
public string CustomizePlusData { get; set; } = string.Empty;
|
public string CustomizePlusData { get; set; } = string.Empty;
|
||||||
|
public string PalettePlusData { get; set; } = string.Empty;
|
||||||
public string ManipulationData { get; set; } = string.Empty;
|
public string ManipulationData { get; set; } = string.Empty;
|
||||||
public List<FileData> Files { get; set; } = new();
|
public List<FileData> Files { get; set; } = new();
|
||||||
public List<FileSwap> FileSwaps { get; set; } = new();
|
public List<FileSwap> FileSwaps { get; set; } = new();
|
||||||
@@ -26,6 +27,7 @@ public record MareCharaFileData
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomizePlusData = dto.CustomizePlusData;
|
CustomizePlusData = dto.CustomizePlusData;
|
||||||
|
PalettePlusData = dto.PalettePlusData;
|
||||||
ManipulationData = dto.ManipulationData;
|
ManipulationData = dto.ManipulationData;
|
||||||
|
|
||||||
if (dto.FileReplacements.TryGetValue(ObjectKind.Player, out var fileReplacements))
|
if (dto.FileReplacements.TryGetValue(ObjectKind.Player, out var fileReplacements))
|
||||||
|
|||||||
@@ -326,6 +326,7 @@ public class CharacterDataFactory
|
|||||||
previousData.GlamourerString[objectKind] = _ipcManager.GlamourerGetCharacterCustomization(charaPointer);
|
previousData.GlamourerString[objectKind] = _ipcManager.GlamourerGetCharacterCustomization(charaPointer);
|
||||||
previousData.HeelsOffset = _ipcManager.GetHeelsOffset();
|
previousData.HeelsOffset = _ipcManager.GetHeelsOffset();
|
||||||
previousData.CustomizePlusScale = _ipcManager.GetCustomizePlusScale();
|
previousData.CustomizePlusScale = _ipcManager.GetCustomizePlusScale();
|
||||||
|
previousData.PalettePlusPalette = _ipcManager.PalettePlusGetPalette();
|
||||||
|
|
||||||
Logger.Debug("Handling transient update for " + objectKind);
|
Logger.Debug("Handling transient update for " + objectKind);
|
||||||
ManageSemiTransientData(previousData, objectKind, charaPointer);
|
ManageSemiTransientData(previousData, objectKind, charaPointer);
|
||||||
|
|||||||
@@ -129,6 +129,14 @@ public class CachedPlayer : IDisposable
|
|||||||
charaDataToUpdate.Add(objectKind);
|
charaDataToUpdate.Add(objectKind);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool palettePlusDataDifferent = !string.Equals(_cachedData.PalettePlusData, characterData.PalettePlusData, StringComparison.Ordinal);
|
||||||
|
if (palettePlusDataDifferent)
|
||||||
|
{
|
||||||
|
Logger.Debug("Updating " + objectKind);
|
||||||
|
charaDataToUpdate.Add(objectKind);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +157,15 @@ public class CachedPlayer : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(characterData.PalettePlusData))
|
||||||
|
{
|
||||||
|
if (!warning.ShownPalettePlusWarning && !_ipcManager.CheckPalettePlusApi())
|
||||||
|
{
|
||||||
|
_dalamudUtil.PrintWarnChat("Received Palette+ data for player " + PlayerName + ", but Palette+ is not installed. Install Palette+ to experience their character fully.");
|
||||||
|
warning.ShownPalettePlusWarning = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_cachedData = characterData;
|
_cachedData = characterData;
|
||||||
|
|
||||||
DownloadAndApplyCharacter(charaDataToUpdate, updateModdedPaths);
|
DownloadAndApplyCharacter(charaDataToUpdate, updateModdedPaths);
|
||||||
@@ -244,6 +261,7 @@ public class CachedPlayer : IDisposable
|
|||||||
ct.ThrowIfCancellationRequested();
|
ct.ThrowIfCancellationRequested();
|
||||||
_ipcManager.HeelsSetOffsetForPlayer(_cachedData.HeelsOffset, PlayerCharacter);
|
_ipcManager.HeelsSetOffsetForPlayer(_cachedData.HeelsOffset, PlayerCharacter);
|
||||||
_ipcManager.CustomizePlusSetBodyScale(PlayerCharacter, _cachedData.CustomizePlusData);
|
_ipcManager.CustomizePlusSetBodyScale(PlayerCharacter, _cachedData.CustomizePlusData);
|
||||||
|
_ipcManager.PalettePlusSetPalette(PlayerCharacter, _cachedData.PalettePlusData);
|
||||||
RequestedPenumbraRedraw = true;
|
RequestedPenumbraRedraw = true;
|
||||||
Logger.Debug(
|
Logger.Debug(
|
||||||
$"Request Redraw for {PlayerName}");
|
$"Request Redraw for {PlayerName}");
|
||||||
@@ -449,6 +467,7 @@ public class CachedPlayer : IDisposable
|
|||||||
_ipcManager.GlamourerApplyOnlyEquipment(_lastGlamourerData, PlayerCharacter);
|
_ipcManager.GlamourerApplyOnlyEquipment(_lastGlamourerData, PlayerCharacter);
|
||||||
_ipcManager.HeelsRestoreOffsetForPlayer(PlayerCharacter);
|
_ipcManager.HeelsRestoreOffsetForPlayer(PlayerCharacter);
|
||||||
_ipcManager.CustomizePlusRevert(PlayerCharacter);
|
_ipcManager.CustomizePlusRevert(PlayerCharacter);
|
||||||
|
_ipcManager.PalettePlusRemovePalette(PlayerCharacter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ public class IpcManager : IDisposable
|
|||||||
private readonly ICallGateSubscriber<Character?, object> _customizePlusRevert;
|
private readonly ICallGateSubscriber<Character?, object> _customizePlusRevert;
|
||||||
private readonly ICallGateSubscriber<string?, object> _customizePlusOnScaleUpdate;
|
private readonly ICallGateSubscriber<string?, object> _customizePlusOnScaleUpdate;
|
||||||
|
|
||||||
|
private readonly ICallGateSubscriber<string> _palettePlusApiVersion;
|
||||||
|
private readonly ICallGateSubscriber<Character, string> _palettePlusGetCharaPalette;
|
||||||
|
private readonly ICallGateSubscriber<Character, string, object> _palettePlusSetCharaPalette;
|
||||||
|
private readonly ICallGateSubscriber<Character, object> _palettePlusRemoveCharaPalette;
|
||||||
|
private readonly ICallGateSubscriber<Character, string, object> _palettePlusPaletteChanged;
|
||||||
|
|
||||||
private readonly DalamudUtil _dalamudUtil;
|
private readonly DalamudUtil _dalamudUtil;
|
||||||
private bool _inGposeQueueMode = false;
|
private bool _inGposeQueueMode = false;
|
||||||
private ConcurrentQueue<Action> ActionQueue => _inGposeQueueMode ? _gposeActionQueue : _normalQueue;
|
private ConcurrentQueue<Action> ActionQueue => _inGposeQueueMode ? _gposeActionQueue : _normalQueue;
|
||||||
@@ -103,6 +109,14 @@ public class IpcManager : IDisposable
|
|||||||
|
|
||||||
_customizePlusOnScaleUpdate.Subscribe(OnCustomizePlusScaleChange);
|
_customizePlusOnScaleUpdate.Subscribe(OnCustomizePlusScaleChange);
|
||||||
|
|
||||||
|
_palettePlusApiVersion = pi.GetIpcSubscriber<string>("PalettePlus.ApiVersion");
|
||||||
|
_palettePlusGetCharaPalette = pi.GetIpcSubscriber<Character, string>("PalettePlus.GetCharaPalette");
|
||||||
|
_palettePlusSetCharaPalette = pi.GetIpcSubscriber<Character, string, object>("PalettePlus.SetCharaPalette");
|
||||||
|
_palettePlusRemoveCharaPalette = pi.GetIpcSubscriber<Character, object>("PalettePlus.RemoveCharaPalette");
|
||||||
|
_palettePlusPaletteChanged = pi.GetIpcSubscriber<Character, string, object>("PalettePlus.PaletteChanged");
|
||||||
|
|
||||||
|
_palettePlusPaletteChanged.Subscribe(OnPalettePlusPaletteChange);
|
||||||
|
|
||||||
if (Initialized)
|
if (Initialized)
|
||||||
{
|
{
|
||||||
PenumbraInitialized?.Invoke();
|
PenumbraInitialized?.Invoke();
|
||||||
@@ -168,6 +182,7 @@ public class IpcManager : IDisposable
|
|||||||
public event FloatDelegate? HeelsOffsetChangeEvent;
|
public event FloatDelegate? HeelsOffsetChangeEvent;
|
||||||
public event PenumbraFileResourceDelegate? PenumbraResourceLoadEvent;
|
public event PenumbraFileResourceDelegate? PenumbraResourceLoadEvent;
|
||||||
public event StringDelegate? CustomizePlusScaleChange;
|
public event StringDelegate? CustomizePlusScaleChange;
|
||||||
|
public event StringDelegate? PalettePlusPaletteChange;
|
||||||
|
|
||||||
public bool Initialized => CheckPenumbraApi();
|
public bool Initialized => CheckPenumbraApi();
|
||||||
public bool CheckGlamourerApi()
|
public bool CheckGlamourerApi()
|
||||||
@@ -218,6 +233,18 @@ public class IpcManager : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CheckPalettePlusApi()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return string.Equals(_palettePlusApiVersion.InvokeFunc(), "1.0.0", StringComparison.Ordinal);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Logger.Verbose("Disposing " + nameof(IpcManager));
|
Logger.Verbose("Disposing " + nameof(IpcManager));
|
||||||
@@ -503,6 +530,59 @@ public class IpcManager : IDisposable
|
|||||||
CustomizePlusScaleChange?.Invoke(scale);
|
CustomizePlusScaleChange?.Invoke(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnPalettePlusPaletteChange(Character character, string palette)
|
||||||
|
{
|
||||||
|
if (character.Address == 0 || character.Address != _dalamudUtil.PlayerPointer) return;
|
||||||
|
if (palette != null) palette = Convert.ToBase64String(Encoding.UTF8.GetBytes(palette));
|
||||||
|
PalettePlusPaletteChange?.Invoke(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PalettePlusSetPalette(IntPtr character, string palette)
|
||||||
|
{
|
||||||
|
if (!CheckPalettePlusApi()) return;
|
||||||
|
ActionQueue.Enqueue(() =>
|
||||||
|
{
|
||||||
|
var gameObj = _dalamudUtil.CreateGameObject(character);
|
||||||
|
if (gameObj is Character c)
|
||||||
|
{
|
||||||
|
string decodedPalette = Encoding.UTF8.GetString(Convert.FromBase64String(palette));
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(decodedPalette))
|
||||||
|
{
|
||||||
|
Logger.Verbose("PalettePlus removing for " + c.Address.ToString("X"));
|
||||||
|
_palettePlusRemoveCharaPalette!.InvokeAction(c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Verbose("PalettePlus applying for " + c.Address.ToString("X"));
|
||||||
|
_palettePlusSetCharaPalette!.InvokeAction(c, decodedPalette);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PalettePlusGetPalette()
|
||||||
|
{
|
||||||
|
if (!CheckPalettePlusApi()) return string.Empty;
|
||||||
|
var palette = _palettePlusGetCharaPalette.InvokeFunc(_dalamudUtil.PlayerCharacter);
|
||||||
|
if (string.IsNullOrEmpty(palette)) return string.Empty;
|
||||||
|
return Convert.ToBase64String(Encoding.UTF8.GetBytes(palette));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PalettePlusRemovePalette(IntPtr character)
|
||||||
|
{
|
||||||
|
if (!CheckPalettePlusApi()) return;
|
||||||
|
ActionQueue.Enqueue(() =>
|
||||||
|
{
|
||||||
|
var gameObj = _dalamudUtil.CreateGameObject(character);
|
||||||
|
if (gameObj is Character c)
|
||||||
|
{
|
||||||
|
Logger.Verbose("PalettePlus removing for " + c.Address.ToString("X"));
|
||||||
|
_palettePlusRemoveCharaPalette!.InvokeAction(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void PenumbraDispose()
|
private void PenumbraDispose()
|
||||||
{
|
{
|
||||||
PenumbraDisposed?.Invoke();
|
PenumbraDisposed?.Invoke();
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ public class PlayerManager : IDisposable
|
|||||||
_dalamudUtil.DelayedFrameworkUpdate += DalamudUtilOnDelayedFrameworkUpdate;
|
_dalamudUtil.DelayedFrameworkUpdate += DalamudUtilOnDelayedFrameworkUpdate;
|
||||||
_ipcManager.HeelsOffsetChangeEvent += HeelsOffsetChanged;
|
_ipcManager.HeelsOffsetChangeEvent += HeelsOffsetChanged;
|
||||||
_ipcManager.CustomizePlusScaleChange += CustomizePlusChanged;
|
_ipcManager.CustomizePlusScaleChange += CustomizePlusChanged;
|
||||||
|
_ipcManager.PalettePlusPaletteChange += PalettePlusChanged;
|
||||||
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
||||||
|
|
||||||
|
|
||||||
@@ -118,6 +119,17 @@ public class PlayerManager : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PalettePlusChanged(string? change)
|
||||||
|
{
|
||||||
|
change ??= string.Empty;
|
||||||
|
var player = _playerRelatedObjects.First(f => f.ObjectKind == ObjectKind.Player);
|
||||||
|
if (LastCreatedCharacterData != null && !string.Equals(LastCreatedCharacterData.PalettePlusData, change, StringComparison.Ordinal) && !player.IsProcessing)
|
||||||
|
{
|
||||||
|
Logger.Debug("PalettePlus data changed to " + change);
|
||||||
|
player.HasTransientsUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Logger.Verbose("Disposing " + nameof(PlayerManager));
|
Logger.Verbose("Disposing " + nameof(PlayerManager));
|
||||||
@@ -134,6 +146,7 @@ public class PlayerManager : IDisposable
|
|||||||
_playerChangedCts?.Cancel();
|
_playerChangedCts?.Cancel();
|
||||||
_ipcManager.HeelsOffsetChangeEvent -= HeelsOffsetChanged;
|
_ipcManager.HeelsOffsetChangeEvent -= HeelsOffsetChanged;
|
||||||
_ipcManager.CustomizePlusScaleChange -= CustomizePlusChanged;
|
_ipcManager.CustomizePlusScaleChange -= CustomizePlusChanged;
|
||||||
|
_ipcManager.PalettePlusPaletteChange -= PalettePlusChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void DalamudUtilOnDelayedFrameworkUpdate()
|
private unsafe void DalamudUtilOnDelayedFrameworkUpdate()
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ public class CharacterData
|
|||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public string CustomizePlusScale { get; set; } = string.Empty;
|
public string CustomizePlusScale { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonProperty]
|
||||||
|
public string PalettePlusPalette { get; set; } = string.Empty;
|
||||||
|
|
||||||
public void AddFileReplacement(ObjectKind objectKind, FileReplacement fileReplacement)
|
public void AddFileReplacement(ObjectKind objectKind, FileReplacement fileReplacement)
|
||||||
{
|
{
|
||||||
if (!fileReplacement.HasFileReplacement) return;
|
if (!fileReplacement.HasFileReplacement) return;
|
||||||
@@ -74,6 +77,7 @@ public class CharacterData
|
|||||||
ManipulationData = ManipulationString,
|
ManipulationData = ManipulationString,
|
||||||
HeelsOffset = HeelsOffset,
|
HeelsOffset = HeelsOffset,
|
||||||
CustomizePlusData = CustomizePlusScale,
|
CustomizePlusData = CustomizePlusScale,
|
||||||
|
PalettePlusData = PalettePlusPalette,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ public record OptionalPluginWarning
|
|||||||
{
|
{
|
||||||
public bool ShownHeelsWarning { get; set; } = false;
|
public bool ShownHeelsWarning { get; set; } = false;
|
||||||
public bool ShownCustomizePlusWarning { get; set; } = false;
|
public bool ShownCustomizePlusWarning { get; set; } = false;
|
||||||
|
public bool ShownPalettePlusWarning { get; set; } = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public class Pair
|
|||||||
{
|
{
|
||||||
ShownCustomizePlusWarning = _configService.Current.DisableOptionalPluginWarnings,
|
ShownCustomizePlusWarning = _configService.Current.DisableOptionalPluginWarnings,
|
||||||
ShownHeelsWarning = _configService.Current.DisableOptionalPluginWarnings,
|
ShownHeelsWarning = _configService.Current.DisableOptionalPluginWarnings,
|
||||||
|
ShownPalettePlusWarning = _configService.Current.DisableOptionalPluginWarnings,
|
||||||
};
|
};
|
||||||
|
|
||||||
CachedPlayer.Initialize(address, name);
|
CachedPlayer.Initialize(address, name);
|
||||||
@@ -91,6 +92,7 @@ public class Pair
|
|||||||
{
|
{
|
||||||
ShownCustomizePlusWarning = _configService.Current.DisableOptionalPluginWarnings,
|
ShownCustomizePlusWarning = _configService.Current.DisableOptionalPluginWarnings,
|
||||||
ShownHeelsWarning = _configService.Current.DisableOptionalPluginWarnings,
|
ShownHeelsWarning = _configService.Current.DisableOptionalPluginWarnings,
|
||||||
|
ShownPalettePlusWarning = _configService.Current.DisableOptionalPluginWarnings,
|
||||||
};
|
};
|
||||||
|
|
||||||
CachedPlayer.ApplyCharacterData(RemoveNotSyncedFiles(LastReceivedCharacterData.DeepClone())!, _pluginWarnings);
|
CachedPlayer.ApplyCharacterData(RemoveNotSyncedFiles(LastReceivedCharacterData.DeepClone())!, _pluginWarnings);
|
||||||
|
|||||||
@@ -181,11 +181,13 @@ public partial class UiShared : IDisposable
|
|||||||
var glamourerExists = _ipcManager.CheckGlamourerApi();
|
var glamourerExists = _ipcManager.CheckGlamourerApi();
|
||||||
var heelsExists = _ipcManager.CheckHeelsApi();
|
var heelsExists = _ipcManager.CheckHeelsApi();
|
||||||
var customizeExists = _ipcManager.CheckCustomizePlusApi();
|
var customizeExists = _ipcManager.CheckCustomizePlusApi();
|
||||||
|
var paletteExists = _ipcManager.CheckPalettePlusApi();
|
||||||
|
|
||||||
var penumbraColor = penumbraExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
var penumbraColor = penumbraExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||||
var glamourerColor = glamourerExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
var glamourerColor = glamourerExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||||
var heelsColor = heelsExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
var heelsColor = heelsExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||||
var customizeColor = customizeExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
var customizeColor = customizeExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||||
|
var paletteColor = paletteExists ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||||
ImGui.Text("Penumbra:");
|
ImGui.Text("Penumbra:");
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextColored(penumbraColor, penumbraExists ? "Available" : "Unavailable");
|
ImGui.TextColored(penumbraColor, penumbraExists ? "Available" : "Unavailable");
|
||||||
@@ -202,6 +204,10 @@ public partial class UiShared : IDisposable
|
|||||||
ImGui.Text("Customize+:");
|
ImGui.Text("Customize+:");
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextColored(customizeColor, customizeExists ? "Available" : "Unavailable");
|
ImGui.TextColored(customizeColor, customizeExists ? "Available" : "Unavailable");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.Text("PalettePlus+:");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextColored(paletteColor, paletteExists ? "Available" : "Unavailable");
|
||||||
|
|
||||||
if (!penumbraExists || !glamourerExists)
|
if (!penumbraExists || !glamourerExists)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user