nearby lightfinder users window, wiht pair func

This commit is contained in:
choco
2025-12-27 02:38:56 +01:00
parent 1ab4e2f94b
commit 5eed65149a
4 changed files with 366 additions and 36 deletions

View File

@@ -519,7 +519,7 @@ public class CompactUi : WindowMediatorSubscriberBase
ImGui.InvisibleButton("BroadcastIcon", buttonSize);
var iconPos = ImGui.GetItemRectMin() + new Vector2(0f, iconYOffset);
using (_uiSharedService.IconFont.Push())
ImGui.GetWindowDrawList().AddText(iconPos, ImGui.GetColorU32(UIColors.Get("LightlessGreen")), FontAwesomeIcon.PersonCirclePlus.ToIconString());
ImGui.GetWindowDrawList().AddText(iconPos, ImGui.GetColorU32(UIColors.Get("LightlessGreen")), FontAwesomeIcon.Wifi.ToIconString());
nextIconX = ImGui.GetItemRectMax().X + 6f;
@@ -640,6 +640,7 @@ public class CompactUi : WindowMediatorSubscriberBase
}
}
if (uidTextHovered)
{
var padding = new Vector2(35f * ImGuiHelpers.GlobalScale);

View File

@@ -11,7 +11,9 @@ using LightlessSync.API.Data.Extensions;
using LightlessSync.API.Dto;
using LightlessSync.API.Dto.Group;
using LightlessSync.LightlessConfiguration;
using LightlessSync.PlayerData.Pairs;
using LightlessSync.Services;
using LightlessSync.Services.ActorTracking;
using LightlessSync.Services.LightFinder;
using LightlessSync.Services.Mediator;
using LightlessSync.UI.Services;
@@ -28,6 +30,7 @@ public class LightFinderUI : WindowMediatorSubscriberBase
{
#region Services
private readonly ActorObjectService _actorObjectService;
private readonly ApiController _apiController;
private readonly DalamudUtilService _dalamudUtilService;
private readonly LightFinderScannerService _broadcastScannerService;
@@ -63,10 +66,10 @@ public class LightFinderUI : WindowMediatorSubscriberBase
private LightfinderTab _selectedTab = LightfinderTab.NearbySyncshells;
private string _userUid = string.Empty;
private enum LightfinderTab { NearbySyncshells, BroadcastSettings, Help }
private enum LightfinderTab { NearbySyncshells, NearbyPlayers, BroadcastSettings, Help }
#if DEBUG
private enum LightfinderTabDebug { NearbySyncshells, BroadcastSettings, Help, Debug }
private enum LightfinderTabDebug { NearbySyncshells, NearbyPlayers, BroadcastSettings, Help, Debug }
private LightfinderTabDebug _selectedTabDebug = LightfinderTabDebug.NearbySyncshells;
#endif
@@ -89,7 +92,8 @@ public class LightFinderUI : WindowMediatorSubscriberBase
LightFinderScannerService broadcastScannerService,
PairUiService pairUiService,
DalamudUtilService dalamudUtilService,
LightlessProfileManager lightlessProfileManager
LightlessProfileManager lightlessProfileManager,
ActorObjectService actorObjectService
) : base(logger, mediator, "Lightfinder###LightlessLightfinderUI", performanceCollectorService)
{
_broadcastService = broadcastService;
@@ -100,6 +104,7 @@ public class LightFinderUI : WindowMediatorSubscriberBase
_pairUiService = pairUiService;
_dalamudUtilService = dalamudUtilService;
_lightlessProfileManager = lightlessProfileManager;
_actorObjectService = actorObjectService;
_animatedHeader.Height = 100f;
_animatedHeader.EnableBottomGradient = true;
@@ -158,6 +163,7 @@ public class LightFinderUI : WindowMediatorSubscriberBase
var debugTabOptions = new List<UiSharedService.TabOption<LightfinderTabDebug>>
{
new("Nearby Syncshells", LightfinderTabDebug.NearbySyncshells),
new("Nearby Players", LightfinderTabDebug.NearbyPlayers),
new("Broadcast", LightfinderTabDebug.BroadcastSettings),
new("Help", LightfinderTabDebug.Help),
new("Debug", LightfinderTabDebug.Debug)
@@ -171,6 +177,9 @@ public class LightFinderUI : WindowMediatorSubscriberBase
case LightfinderTabDebug.NearbySyncshells:
DrawNearbySyncshellsTab();
break;
case LightfinderTabDebug.NearbyPlayers:
DrawNearbyPlayersTab();
break;
case LightfinderTabDebug.BroadcastSettings:
DrawBroadcastSettingsTab();
break;
@@ -185,6 +194,7 @@ public class LightFinderUI : WindowMediatorSubscriberBase
var tabOptions = new List<UiSharedService.TabOption<LightfinderTab>>
{
new("Nearby Syncshells", LightfinderTab.NearbySyncshells),
new("Nearby Players", LightfinderTab.NearbyPlayers),
new("Broadcast", LightfinderTab.BroadcastSettings),
new("Help", LightfinderTab.Help)
};
@@ -197,6 +207,9 @@ public class LightFinderUI : WindowMediatorSubscriberBase
case LightfinderTab.NearbySyncshells:
DrawNearbySyncshellsTab();
break;
case LightfinderTab.NearbyPlayers:
DrawNearbyPlayersTab();
break;
case LightfinderTab.BroadcastSettings:
DrawBroadcastSettingsTab();
break;
@@ -241,8 +254,8 @@ public class LightFinderUI : WindowMediatorSubscriberBase
{
ImGui.TableSetupColumn("Status", ImGuiTableColumnFlags.WidthStretch, 1f);
ImGui.TableSetupColumn("Time", ImGuiTableColumnFlags.WidthStretch, 1f);
ImGui.TableSetupColumn("NearbyPlayers", ImGuiTableColumnFlags.WidthStretch, 1f);
ImGui.TableSetupColumn("NearbySyncshells", ImGuiTableColumnFlags.WidthStretch, 1f);
ImGui.TableSetupColumn("NearbyPlayers", ImGuiTableColumnFlags.WidthStretch, 1f);
ImGui.TableSetupColumn("Broadcasting", ImGuiTableColumnFlags.WidthStretch, 1f);
ImGui.TableSetupColumn("Button", ImGuiTableColumnFlags.WidthFixed, buttonWidth + 16f * scale);
@@ -278,16 +291,18 @@ public class LightFinderUI : WindowMediatorSubscriberBase
}
DrawStatusCell(FontAwesomeIcon.Clock, timeColor, timeValue, timeSub, infoColor, scale);
// Nearby players cell
var nearbyPlayerCount = _broadcastScannerService.CountActiveBroadcasts();
var nearbyPlayerColor = nearbyPlayerCount > 0 ? UIColors.Get("LightlessBlue") : infoColor;
DrawStatusCell(FontAwesomeIcon.Users, nearbyPlayerColor, nearbyPlayerCount.ToString(), "Players", infoColor, scale);
// Nearby syncshells cell
var nearbySyncshellCount = _nearbySyncshells.Count;
var nearbySyncshellColor = nearbySyncshellCount > 0 ? UIColors.Get("LightlessPurple") : infoColor;
DrawStatusCell(FontAwesomeIcon.Compass, nearbySyncshellColor, nearbySyncshellCount.ToString(), "Syncshells", infoColor, scale);
// Nearby players cell (exclude self)
string? myHashedCidForCount = null;
try { myHashedCidForCount = _dalamudUtilService.GetCID().ToString().GetHash256(); } catch { }
var nearbyPlayerCount = _broadcastScannerService.CountActiveBroadcasts(myHashedCidForCount);
var nearbyPlayerColor = nearbyPlayerCount > 0 ? UIColors.Get("LightlessBlue") : infoColor;
DrawStatusCell(FontAwesomeIcon.Users, nearbyPlayerColor, nearbyPlayerCount.ToString(), "Players", infoColor, scale);
// Broadcasting syncshell cell
var isBroadcastingSyncshell = _configService.Current.SyncshellFinderEnabled && isBroadcasting;
var broadcastSyncshellColor = isBroadcastingSyncshell ? UIColors.Get("LightlessGreen") : infoColor;
@@ -409,7 +424,7 @@ public class LightFinderUI : WindowMediatorSubscriberBase
}
}
private List<(GroupJoinDto Shell, string BroadcasterName)> BuildSyncshellCardData()
private List<(GroupJoinDto Shell, string BroadcasterName, bool IsOwnBroadcast)> BuildSyncshellCardData()
{
string? myHashedCid = null;
try
@@ -419,11 +434,9 @@ public class LightFinderUI : WindowMediatorSubscriberBase
}
catch { }
var broadcasts = _broadcastScannerService.GetActiveSyncshellBroadcasts()
.Where(b => !string.Equals(b.HashedCID, myHashedCid, StringComparison.Ordinal))
.ToList();
var broadcasts = _broadcastScannerService.GetActiveSyncshellBroadcasts().ToList();
var cardData = new List<(GroupJoinDto Shell, string BroadcasterName)>();
var cardData = new List<(GroupJoinDto Shell, string BroadcasterName, bool IsOwnBroadcast)>();
foreach (var shell in _nearbySyncshells)
{
@@ -434,7 +447,7 @@ public class LightFinderUI : WindowMediatorSubscriberBase
if (_useTestSyncshells)
{
var displayName = !string.IsNullOrEmpty(shell.Group.Alias) ? shell.Group.Alias : shell.Group.GID;
cardData.Add((shell, $"{displayName} (Test World)"));
cardData.Add((shell, $"{displayName} (Test World)", false));
continue;
}
#endif
@@ -443,29 +456,39 @@ public class LightFinderUI : WindowMediatorSubscriberBase
if (broadcast == null)
continue;
var (name, address) = _dalamudUtilService.FindPlayerByNameHash(broadcast.HashedCID);
if (string.IsNullOrEmpty(name))
continue;
var isOwnBroadcast = !string.IsNullOrEmpty(myHashedCid) && string.Equals(broadcast.HashedCID, myHashedCid, StringComparison.Ordinal);
var worldName = _dalamudUtilService.GetWorldNameFromPlayerAddress(address);
var broadcasterName = !string.IsNullOrEmpty(worldName) ? $"{name} ({worldName})" : name;
string broadcasterName;
if (isOwnBroadcast)
{
broadcasterName = "You";
}
else
{
var (name, address) = _dalamudUtilService.FindPlayerByNameHash(broadcast.HashedCID);
if (string.IsNullOrEmpty(name))
continue;
cardData.Add((shell, broadcasterName));
var worldName = _dalamudUtilService.GetWorldNameFromPlayerAddress(address);
broadcasterName = !string.IsNullOrEmpty(worldName) ? $"{name} ({worldName})" : name;
}
cardData.Add((shell, broadcasterName, isOwnBroadcast));
}
return cardData;
}
private void DrawSyncshellList(List<(GroupJoinDto Shell, string BroadcasterName)> listData)
private void DrawSyncshellList(List<(GroupJoinDto Shell, string BroadcasterName, bool IsOwnBroadcast)> listData)
{
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 8f);
ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 1f);
if (ImGui.BeginChild("SyncshellListScroll", new Vector2(-1, -1), border: false))
{
foreach (var (shell, broadcasterName) in listData)
foreach (var (shell, broadcasterName, isOwnBroadcast) in listData)
{
DrawSyncshellListItem(shell, broadcasterName);
DrawSyncshellListItem(shell, broadcasterName, isOwnBroadcast);
ImGui.Dummy(new Vector2(0, 2 * ImGuiHelpers.GlobalScale));
}
}
@@ -474,7 +497,7 @@ public class LightFinderUI : WindowMediatorSubscriberBase
ImGui.PopStyleVar(2);
}
private void DrawSyncshellListItem(GroupJoinDto shell, string broadcasterName)
private void DrawSyncshellListItem(GroupJoinDto shell, string broadcasterName, bool isOwnBroadcast)
{
ImGui.PushID(shell.Group.GID);
float rowHeight = 74f * ImGuiHelpers.GlobalScale;
@@ -496,9 +519,12 @@ public class LightFinderUI : WindowMediatorSubscriberBase
float rightX = startX + regionW - rightTxtW - style.ItemSpacing.X;
ImGui.SameLine();
ImGui.SetCursorPosX(rightX);
ImGui.TextUnformatted(broadcasterName);
if (isOwnBroadcast)
ImGui.TextColored(UIColors.Get("LightlessGreen"), broadcasterName);
else
ImGui.TextUnformatted(broadcasterName);
if (ImGui.IsItemHovered())
ImGui.SetTooltip("Broadcaster");
ImGui.SetTooltip(isOwnBroadcast ? "Your broadcast" : "Broadcaster");
UiSharedService.ColoredSeparator(UIColors.Get("LightlessPurpleDefault"));
@@ -530,21 +556,21 @@ public class LightFinderUI : WindowMediatorSubscriberBase
ImGui.PopID();
}
private void DrawSyncshellGrid(List<(GroupJoinDto Shell, string BroadcasterName)> cardData)
private void DrawSyncshellGrid(List<(GroupJoinDto Shell, string BroadcasterName, bool IsOwnBroadcast)> cardData)
{
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 8f);
ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 1f);
foreach (var (shell, _) in cardData)
foreach (var (shell, _, isOwnBroadcast) in cardData)
{
DrawSyncshellCompactItem(shell);
DrawSyncshellCompactItem(shell, isOwnBroadcast);
ImGui.Dummy(new Vector2(0, 2 * ImGuiHelpers.GlobalScale));
}
ImGui.PopStyleVar(2);
}
private void DrawSyncshellCompactItem(GroupJoinDto shell)
private void DrawSyncshellCompactItem(GroupJoinDto shell, bool isOwnBroadcast)
{
ImGui.PushID(shell.Group.GID);
float rowHeight = 36f * ImGuiHelpers.GlobalScale;
@@ -552,11 +578,13 @@ public class LightFinderUI : WindowMediatorSubscriberBase
ImGui.BeginChild($"ShellCompact##{shell.Group.GID}", new Vector2(-1, rowHeight), border: true);
var displayName = !string.IsNullOrEmpty(shell.Group.Alias) ? shell.Group.Alias : shell.Group.GID;
if (isOwnBroadcast)
displayName += " (You)";
var style = ImGui.GetStyle();
float availW = ImGui.GetContentRegionAvail().X;
ImGui.AlignTextToFramePadding();
_uiSharedService.MediumText(displayName, UIColors.Get("LightlessPurple"));
_uiSharedService.MediumText(displayName, isOwnBroadcast ? UIColors.Get("LightlessGreen") : UIColors.Get("LightlessPurple"));
if (ImGui.IsItemHovered())
ImGui.SetTooltip("Click to open profile.");
if (ImGui.IsItemClicked())
@@ -605,7 +633,7 @@ public class LightFinderUI : WindowMediatorSubscriberBase
using (ImRaii.Disabled())
ImGui.Button(label, buttonSize);
UiSharedService.AttachToolTip("You can't join your own Syncshell, silly! That's like trying to high-five yourself.");
UiSharedService.AttachToolTip("You can't join your own Syncshell...");
}
else if (!isAlreadyMember && !isRecentlyJoined)
{
@@ -718,6 +746,284 @@ public class LightFinderUI : WindowMediatorSubscriberBase
#endregion
#region Nearby Players Tab
private void DrawNearbyPlayersTab()
{
ImGui.BeginGroup();
string checkboxLabel = "Compact";
float checkboxWidth = ImGui.CalcTextSize(checkboxLabel).X + ImGui.GetFrameHeight() + 8f;
float availWidth = ImGui.GetContentRegionAvail().X;
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + availWidth - checkboxWidth);
ImGui.Checkbox(checkboxLabel, ref _compactView);
ImGui.EndGroup();
ImGui.Dummy(new Vector2(0, 2 * ImGuiHelpers.GlobalScale));
if (!_broadcastService.IsBroadcasting)
{
ImGui.TextColored(UIColors.Get("LightlessYellow"), "Lightfinder must be active to see nearby players.");
return;
}
string? myHashedCid = null;
try
{
var cid = _dalamudUtilService.GetCID();
myHashedCid = cid.ToString().GetHash256();
}
catch { }
var activeBroadcasts = _broadcastScannerService.GetActiveBroadcasts(myHashedCid);
if (activeBroadcasts.Count == 0)
{
ImGui.TextColored(ImGuiColors.DalamudGrey, "No nearby Lightfinder players found.");
return;
}
var playerData = BuildNearbyPlayerData(activeBroadcasts);
if (playerData.Count == 0)
{
ImGui.TextColored(ImGuiColors.DalamudGrey, "No nearby Lightfinder players found.");
return;
}
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 8f);
ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 1f);
if (ImGui.BeginChild("NearbyPlayersScroll", new Vector2(-1, -1), border: false))
{
foreach (var data in playerData)
{
if (_compactView)
DrawNearbyPlayerCompactRow(data);
else
DrawNearbyPlayerRow(data);
ImGui.Dummy(new Vector2(0, 2 * ImGuiHelpers.GlobalScale));
}
}
ImGui.EndChild();
ImGui.PopStyleVar(2);
}
private List<NearbyPlayerData> BuildNearbyPlayerData(List<KeyValuePair<string, LightFinderScannerService.BroadcastEntry>> activeBroadcasts)
{
var snapshot = _pairUiService.GetSnapshot();
var playerData = new List<NearbyPlayerData>();
foreach (var broadcast in activeBroadcasts)
{
var (name, address) = _dalamudUtilService.FindPlayerByNameHash(broadcast.Key);
if (string.IsNullOrEmpty(name) || address == nint.Zero)
continue;
var worldName = _dalamudUtilService.GetWorldNameFromPlayerAddress(address);
var pair = snapshot.PairsByUid.Values.FirstOrDefault(p =>
p.IsVisible &&
!string.IsNullOrEmpty(p.GetPlayerNameHash()) &&
string.Equals(p.GetPlayerNameHash(), broadcast.Key, StringComparison.Ordinal));
var isDirectlyPaired = pair?.IsDirectlyPaired ?? false;
var sharedGroups = pair?.UserPair?.Groups ?? [];
var sharedGroupNames = sharedGroups
.Select(gid => snapshot.GroupsByGid.TryGetValue(gid, out var g) ? g.GroupAliasOrGID : gid)
.ToList();
playerData.Add(new NearbyPlayerData(broadcast.Key, name, worldName, address, pair, isDirectlyPaired, sharedGroupNames));
}
return playerData;
}
private readonly record struct NearbyPlayerData(
string HashedCid,
string Name,
string? World,
nint Address,
Pair? Pair,
bool IsDirectlyPaired,
List<string> SharedSyncshells);
private void DrawNearbyPlayerRow(NearbyPlayerData data)
{
ImGui.PushID(data.HashedCid);
float rowHeight = 74f * ImGuiHelpers.GlobalScale;
ImGui.BeginChild($"PlayerRow##{data.HashedCid}", new Vector2(-1, rowHeight), border: true);
var serverName = !string.IsNullOrEmpty(data.World) ? data.World : "Unknown";
var style = ImGui.GetStyle();
float startX = ImGui.GetCursorPosX();
float regionW = ImGui.GetContentRegionAvail().X;
float rightTxtW = ImGui.CalcTextSize(serverName).X;
_uiSharedService.MediumText(data.Name, UIColors.Get("LightlessPurple"));
if (data.Pair != null)
{
if (ImGui.IsItemHovered())
ImGui.SetTooltip("Click to open profile.");
if (ImGui.IsItemClicked())
Mediator.Publish(new ProfileOpenStandaloneMessage(data.Pair));
}
float rightX = startX + regionW - rightTxtW - style.ItemSpacing.X;
ImGui.SameLine();
ImGui.SetCursorPosX(rightX);
ImGui.TextUnformatted(serverName);
if (ImGui.IsItemHovered())
ImGui.SetTooltip("Home World");
UiSharedService.ColoredSeparator(UIColors.Get("LightlessPurpleDefault"));
Vector2 rowStartLocal = ImGui.GetCursorPos();
if (data.IsDirectlyPaired)
{
ImGui.SetCursorPosX(startX);
_uiSharedService.IconText(FontAwesomeIcon.UserCheck, UIColors.Get("LightlessGreen"));
ImGui.SameLine(0f, 4f * ImGuiHelpers.GlobalScale);
ImGui.TextColored(UIColors.Get("LightlessGreen"), "Direct Pair");
}
else if (data.SharedSyncshells.Count > 0)
{
ImGui.SetCursorPosX(startX);
_uiSharedService.IconText(FontAwesomeIcon.Users, UIColors.Get("LightlessPurple"));
ImGui.SameLine(0f, 4f * ImGuiHelpers.GlobalScale);
var shellText = data.SharedSyncshells.Count == 1
? data.SharedSyncshells[0]
: $"{data.SharedSyncshells.Count} shared shells";
ImGui.TextColored(UIColors.Get("LightlessPurple"), shellText);
if (data.SharedSyncshells.Count > 1 && ImGui.IsItemHovered())
ImGui.SetTooltip(string.Join("\n", data.SharedSyncshells));
}
else
{
ImGui.SetCursorPosX(startX);
_uiSharedService.IconText(FontAwesomeIcon.Wifi, UIColors.Get("LightlessBlue"));
ImGui.SameLine(0f, 4f * ImGuiHelpers.GlobalScale);
ImGui.TextColored(ImGuiColors.DalamudGrey, "Lightfinder User");
}
ImGui.Dummy(new Vector2(0, 4 * ImGuiHelpers.GlobalScale));
DrawPlayerActionButtons(data, startX, regionW, rowStartLocal.Y, style);
ImGui.EndChild();
ImGui.PopID();
}
private void DrawNearbyPlayerCompactRow(NearbyPlayerData data)
{
ImGui.PushID(data.HashedCid);
float rowHeight = 36f * ImGuiHelpers.GlobalScale;
ImGui.BeginChild($"PlayerCompact##{data.HashedCid}", new Vector2(-1, rowHeight), border: true);
ImGui.AlignTextToFramePadding();
if (data.IsDirectlyPaired)
{
_uiSharedService.IconText(FontAwesomeIcon.UserCheck, UIColors.Get("LightlessGreen"));
ImGui.SameLine(0f, 4f * ImGuiHelpers.GlobalScale);
}
else if (data.SharedSyncshells.Count > 0)
{
_uiSharedService.IconText(FontAwesomeIcon.Users, UIColors.Get("LightlessPurple"));
ImGui.SameLine(0f, 4f * ImGuiHelpers.GlobalScale);
}
else
{
_uiSharedService.IconText(FontAwesomeIcon.Wifi, UIColors.Get("LightlessBlue"));
ImGui.SameLine(0f, 4f * ImGuiHelpers.GlobalScale);
}
var displayText = !string.IsNullOrEmpty(data.World) ? $"{data.Name} ({data.World})" : data.Name;
_uiSharedService.MediumText(displayText, UIColors.Get("LightlessPurple"));
if (data.Pair != null)
{
if (ImGui.IsItemHovered())
ImGui.SetTooltip("Click to open profile.");
if (ImGui.IsItemClicked())
Mediator.Publish(new ProfileOpenStandaloneMessage(data.Pair));
}
ImGui.SameLine();
DrawPlayerActionButtons(data, 0, ImGui.GetContentRegionAvail().X, ImGui.GetCursorPosY(), ImGui.GetStyle(), compact: true);
ImGui.EndChild();
ImGui.PopID();
}
private void DrawPlayerActionButtons(NearbyPlayerData data, float startX, float regionW, float rowY, ImGuiStylePtr style, bool compact = false)
{
float buttonWidth = compact ? 60f * ImGuiHelpers.GlobalScale : 80f * ImGuiHelpers.GlobalScale;
float buttonHeight = compact ? 0 : 30f;
float totalButtonsWidth = buttonWidth * 2 + style.ItemSpacing.X;
if (compact)
{
float availX = ImGui.GetContentRegionAvail().X;
float curX = ImGui.GetCursorPosX();
ImGui.SetCursorPosX(curX + availX - totalButtonsWidth);
}
else
{
ImGui.SetCursorPos(new Vector2(startX + regionW - totalButtonsWidth - style.ItemSpacing.X, rowY));
}
using (ImRaii.PushColor(ImGuiCol.Button, UIColors.Get("LightlessGreen")))
using (ImRaii.PushColor(ImGuiCol.ButtonHovered, UIColors.Get("LightlessGreen").WithAlpha(0.85f)))
using (ImRaii.PushColor(ImGuiCol.ButtonActive, UIColors.Get("LightlessGreen").WithAlpha(0.75f)))
using (ImRaii.Disabled(data.IsDirectlyPaired))
{
if (ImGui.Button($"Pair##{data.HashedCid}", new Vector2(buttonWidth, buttonHeight)))
{
_ = SendPairRequestAsync(data.HashedCid);
}
}
if (data.IsDirectlyPaired)
UiSharedService.AttachToolTip("Already directly paired with this player.");
ImGui.SameLine();
using (ImRaii.PushColor(ImGuiCol.Button, UIColors.Get("LightlessPurple")))
using (ImRaii.PushColor(ImGuiCol.ButtonHovered, UIColors.Get("LightlessPurple").WithAlpha(0.85f)))
using (ImRaii.PushColor(ImGuiCol.ButtonActive, UIColors.Get("LightlessPurple").WithAlpha(0.75f)))
{
if (ImGui.Button($"Target##{data.HashedCid}", new Vector2(buttonWidth, buttonHeight)))
{
TargetPlayerByAddress(data.Address);
}
}
}
private async Task SendPairRequestAsync(string hashedCid)
{
if (string.IsNullOrWhiteSpace(hashedCid))
return;
try
{
await _apiController.TryPairWithContentId(hashedCid).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to send pair request to {HashedCid}", hashedCid);
}
}
private void TargetPlayerByAddress(nint address)
{
if (address == nint.Zero)
return;
_dalamudUtilService.TargetPlayerByAddress(address);
}
#endregion
#region Broadcast Settings Tab
private void DrawBroadcastSettingsTab()