Add nameplate color option

This commit is contained in:
Loporrit
2025-02-11 14:09:05 +00:00
parent ea27d1d53b
commit 09d9139478
6 changed files with 146 additions and 2 deletions

View File

@@ -18,6 +18,8 @@ public class MareConfig : IMareConfiguration
public DtrEntry.Colors DtrColorsDefault { get; set; } = default;
public DtrEntry.Colors DtrColorsNotConnected { get; set; } = new(Glow: 0x0428FFu);
public DtrEntry.Colors DtrColorsPairsInRange { get; set; } = new(Glow: 0xFFBA47u);
public bool UseNameColors { get; set; } = false;
public DtrEntry.Colors NameColors { get; set; } = new(Foreground: 0xF5EB67u, Glow: 0x78710Fu);
public bool EnableRightClickMenus { get; set; } = true;
public NotificationLocation ErrorNotification { get; set; } = NotificationLocation.Both;
public string ExportFolder { get; set; } = string.Empty;

View File

@@ -152,6 +152,7 @@ public class MarePlugin : MediatorSubscriberBase, IHostedService
_runtimeServiceScope.ServiceProvider.GetRequiredService<OnlinePlayerManager>();
_runtimeServiceScope.ServiceProvider.GetRequiredService<NotificationService>();
_runtimeServiceScope.ServiceProvider.GetRequiredService<ChatService>();
_runtimeServiceScope.ServiceProvider.GetRequiredService<GuiHookService>();
#if !DEBUG
if (_mareConfigService.Current.LogLevel != LogLevel.Information)

View File

@@ -48,6 +48,7 @@ public class Pair
public bool IsVisible => CachedPlayer?.IsVisible ?? false;
public CharacterData? LastReceivedCharacterData { get; set; }
public string? PlayerName => GetPlayerName();
public uint PlayerCharacterId => GetPlayerCharacterId();
public long LastAppliedDataSize => CachedPlayer?.LastAppliedDataSize ?? -1;
public UserData UserData => UserPair?.User ?? GroupPair.First().Value.User;
@@ -173,6 +174,13 @@ public class Pair
return _serverConfigurationManager.GetNameForUid(UserData.UID);
}
public uint GetPlayerCharacterId()
{
if (CachedPlayer != null)
return CachedPlayer.PlayerCharacterId;
return uint.MaxValue;
}
public string? GetNoteOrName()
{
string? note = GetNote();

View File

@@ -47,7 +47,8 @@ public sealed class Plugin : IDalamudPlugin
public Plugin(IDalamudPluginInterface pluginInterface, ICommandManager commandManager, IDataManager gameData,
IFramework framework, IObjectTable objectTable, IClientState clientState, ICondition condition, IChatGui chatGui,
IGameGui gameGui, IDtrBar dtrBar, IToastGui toastGui, IPluginLog pluginLog, ITargetManager targetManager, IGameLifecycle addonLifecycle,
INotificationManager notificationManager, ITextureProvider textureProvider, IContextMenu contextMenu, IGameInteropProvider gameInteropProvider)
INotificationManager notificationManager, ITextureProvider textureProvider, IContextMenu contextMenu, IGameInteropProvider gameInteropProvider,
INamePlateGui namePlateGui)
{
Plugin.Self = this;
_host = new HostBuilder()
@@ -161,6 +162,8 @@ public sealed class Plugin : IDalamudPlugin
s.GetRequiredService<MareMediator>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<PairManager>(),
s.GetRequiredService<ILogger<GameChatHooks>>(), gameInteropProvider, chatGui,
s.GetRequiredService<MareConfigService>(), s.GetRequiredService<ServerConfigurationManager>()));
collection.AddScoped((s) => new GuiHookService(s.GetRequiredService<ILogger<GuiHookService>>(), s.GetRequiredService<MareMediator>(),
s.GetRequiredService<MareConfigService>(), namePlateGui, s.GetRequiredService<PairManager>()));
collection.AddHostedService(p => p.GetRequiredService<FileCacheManager>());
collection.AddHostedService(p => p.GetRequiredService<MareMediator>());

View File

@@ -0,0 +1,108 @@
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.Gui.NamePlate;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Plugin.Services;
using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services.Mediator;
using MareSynchronos.UI;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.Services;
public class GuiHookService : DisposableMediatorSubscriberBase
{
private readonly ILogger<GuiHookService> _logger;
private readonly MareConfigService _configService;
private readonly INamePlateGui _namePlateGui;
private readonly PairManager _pairManager;
private bool _isModified = false;
public GuiHookService(ILogger<GuiHookService> logger, MareMediator mediator, MareConfigService configService,
INamePlateGui namePlateGui, PairManager pairManager)
: base(logger, mediator)
{
_logger = logger;
_configService = configService;
_namePlateGui = namePlateGui;
_pairManager = pairManager;
_namePlateGui.OnNamePlateUpdate += OnNamePlateUpdate;
_namePlateGui.RequestRedraw();
Mediator.Subscribe<PairHandlerVisibleMessage>(this, (_) => _namePlateGui.RequestRedraw());
}
public void RequestRedraw()
{
if (!_configService.Current.UseNameColors)
{
if (!_isModified)
return;
_isModified = false;
}
_namePlateGui.RequestRedraw();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_namePlateGui.OnNamePlateUpdate -= OnNamePlateUpdate;
_namePlateGui.RequestRedraw();
}
private void OnNamePlateUpdate(INamePlateUpdateContext context, IReadOnlyList<INamePlateUpdateHandler> handlers)
{
if (!_configService.Current.UseNameColors)
return;
var visibleUsersIds = _pairManager.GetOnlineUserPairs().Where(u => u.IsVisible && u.PlayerCharacterId != uint.MaxValue).Select(u => (ulong)u.PlayerCharacterId).ToHashSet();
var colors = _configService.Current.NameColors;
foreach (var handler in handlers)
{
if (visibleUsersIds.Contains(handler.GameObjectId))
{
handler.NameParts.TextWrap = (
BuildColorStartSeString(colors),
BuildColorEndSeString(colors)
);
_isModified = true;
}
}
}
#region Colored SeString
private const byte _colorTypeForeground = 0x13;
private const byte _colorTypeGlow = 0x14;
private static SeString BuildColorStartSeString(DtrEntry.Colors colors)
{
var ssb = new SeStringBuilder();
if (colors.Foreground != default)
ssb.Add(BuildColorStartPayload(_colorTypeForeground, colors.Foreground));
if (colors.Glow != default)
ssb.Add(BuildColorStartPayload(_colorTypeGlow, colors.Glow));
return ssb.Build();
}
private static SeString BuildColorEndSeString(DtrEntry.Colors colors)
{
var ssb = new SeStringBuilder();
if (colors.Glow != default)
ssb.Add(BuildColorEndPayload(_colorTypeGlow));
if (colors.Foreground != default)
ssb.Add(BuildColorEndPayload(_colorTypeForeground));
return ssb.Build();
}
private static RawPayload BuildColorStartPayload(byte colorType, uint color)
=> new(unchecked([0x02, colorType, 0x05, 0xF6, byte.Max((byte)color, 0x01), byte.Max((byte)(color >> 8), 0x01), byte.Max((byte)(color >> 16), 0x01), 0x03]));
private static RawPayload BuildColorEndPayload(byte colorType)
=> new([0x02, colorType, 0x02, 0xEC, 0x03]);
#endregion
}

View File

@@ -49,6 +49,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
private readonly MareCharaFileManager _mareCharaFileManager;
private readonly PairManager _pairManager;
private readonly ChatService _chatService;
private readonly GuiHookService _guiHookService;
private readonly PerformanceCollectorService _performanceCollector;
private readonly ServerConfigurationManager _serverConfigurationManager;
private readonly UiSharedService _uiShared;
@@ -73,7 +74,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
public SettingsUi(ILogger<SettingsUi> logger,
UiSharedService uiShared, MareConfigService configService,
MareCharaFileManager mareCharaFileManager, PairManager pairManager, ChatService chatService,
MareCharaFileManager mareCharaFileManager, PairManager pairManager, ChatService chatService, GuiHookService guiHookService,
ServerConfigurationManager serverConfigurationManager,
MareMediator mediator, PerformanceCollectorService performanceCollector,
DalamudUtilService dalamudUtilService,
@@ -87,6 +88,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
_mareCharaFileManager = mareCharaFileManager;
_pairManager = pairManager;
_chatService = chatService;
_guiHookService = guiHookService;
_serverConfigurationManager = serverConfigurationManager;
_performanceCollector = performanceCollector;
_dalamudUtilService = dalamudUtilService;
@@ -1052,6 +1054,26 @@ public class SettingsUi : WindowMediatorSubscriberBase
}
}
var useNameColors = _configService.Current.UseNameColors;
var nameColors = _configService.Current.NameColors;
if (ImGui.Checkbox("Color nameplates of paired players", ref useNameColors))
{
_configService.Current.UseNameColors = useNameColors;
_configService.Save();
_guiHookService.RequestRedraw();
}
using (ImRaii.Disabled(!useNameColors))
{
using var indent = ImRaii.PushIndent();
if (InputDtrColors("Character Name Color", ref nameColors))
{
_configService.Current.NameColors = nameColors;
_configService.Save();
_guiHookService.RequestRedraw();
}
}
if (ImGui.Checkbox("Show separate Visible group", ref showVisibleSeparate))
{
_configService.Current.ShowVisibleUsersSeparately = showVisibleSeparate;