update settings ui character management

This commit is contained in:
Stanley Dimant
2025-02-17 13:01:13 +01:00
parent 61b6365542
commit bfa41fdd96
5 changed files with 142 additions and 65 deletions

View File

@@ -8,4 +8,5 @@ public record Authentication
public int SecretKeyIdx { get; set; } = -1;
public string? UID { get; set; }
public bool AutoLogin { get; set; } = true;
public ulong? LastSeenCID { get; set; } = null;
}

View File

@@ -270,6 +270,18 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
return await RunOnFrameworkThread(GetPlayerName).ConfigureAwait(false);
}
public async Task<ulong> GetCIDAsync()
{
return await RunOnFrameworkThread(GetCID).ConfigureAwait(false);
}
public unsafe ulong GetCID()
{
EnsureIsOnFramework();
var playerChar = GetPlayerCharacter();
return ((BattleChara*)playerChar.Address)->Character.ContentId;
}
public async Task<string> GetPlayerNameHashedAsync()
{
return await RunOnFrameworkThread(() => GetHashedAccIdFromPlayerPointer(GetPlayerPointer())).ConfigureAwait(false);

View File

@@ -100,6 +100,7 @@ public class ServerConfigurationManager
var charaName = _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult();
var worldId = _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult();
var cid = _dalamudUtil.GetCIDAsync().GetAwaiter().GetResult();
var auth = currentServer.Authentications.FindAll(f => string.Equals(f.CharacterName, charaName) && f.WorldId == worldId);
if (auth.Count >= 2)
@@ -115,6 +116,13 @@ public class ServerConfigurationManager
return null;
}
if (auth.Single().LastSeenCID != cid)
{
auth.Single().LastSeenCID = cid;
_logger.LogTrace("GetOAuth2 accessed, updating CID for {chara} on {world} to {cid}", charaName, worldId, cid);
Save();
}
if (!string.IsNullOrEmpty(auth.Single().UID) && !string.IsNullOrEmpty(currentServer.OAuthToken))
{
_logger.LogTrace("GetOAuth2 accessed, returning {key} ({keyValue}) for {chara} on {world}", auth.Single().UID, string.Join("", currentServer.OAuthToken.Take(10)), charaName, worldId);
@@ -139,12 +147,14 @@ public class ServerConfigurationManager
var charaName = _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult();
var worldId = _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult();
var cid = _dalamudUtil.GetCIDAsync().GetAwaiter().GetResult();
if (!currentServer.Authentications.Any() && currentServer.SecretKeys.Any())
{
currentServer.Authentications.Add(new Authentication()
{
CharacterName = charaName,
WorldId = worldId,
LastSeenCID = cid,
SecretKeyIdx = currentServer.SecretKeys.Last().Key,
});
@@ -165,6 +175,13 @@ public class ServerConfigurationManager
return null;
}
if (auth.Single().LastSeenCID != cid)
{
auth.Single().LastSeenCID = cid;
_logger.LogTrace("GetSecretKey accessed, updating CID for {chara} on {world} to {cid}", charaName, worldId, cid);
Save();
}
if (currentServer.SecretKeys.TryGetValue(auth.Single().SecretKeyIdx, out var secretKey))
{
_logger.LogTrace("GetSecretKey accessed, returning {key} ({keyValue}) for {chara} on {world}", secretKey.FriendlyName, string.Join("", secretKey.Key.Take(10)), charaName, worldId);
@@ -250,6 +267,7 @@ public class ServerConfigurationManager
CharacterName = _dalamudUtil.GetPlayerNameAsync().GetAwaiter().GetResult(),
WorldId = _dalamudUtil.GetHomeWorldIdAsync().GetAwaiter().GetResult(),
SecretKeyIdx = !server.UseOAuth2 ? server.SecretKeys.Last().Key : -1,
LastSeenCID = _dalamudUtil.GetCIDAsync().GetAwaiter().GetResult()
});
Save();
}

View File

@@ -1,5 +1,6 @@
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility;
@@ -29,6 +30,7 @@ using System.Globalization;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Numerics;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Json;
@@ -65,6 +67,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
private CancellationTokenSource? _validationCts;
private Task<List<FileCacheEntity>>? _validationTask;
private bool _wasOpen = false;
public SettingsUi(ILogger<SettingsUi> logger,
UiSharedService uiShared, MareConfigService configService,
PairManager pairManager,
@@ -1405,6 +1408,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
" Make sure to enter the character names correctly or use the 'Add current character' button at the bottom.", ImGuiColors.DalamudYellow);
int i = 0;
_uiShared.DrawUpdateOAuthUIDsButton(selectedServer);
if (selectedServer.UseOAuth2 && !string.IsNullOrEmpty(selectedServer.OAuthToken))
{
bool hasSetSecretKeysButNoUid = selectedServer.Authentications.Exists(u => u.SecretKeyIdx != -1 && string.IsNullOrEmpty(u.UID));
@@ -1452,6 +1456,35 @@ public class SettingsUi : WindowMediatorSubscriberBase
}
}
ImGui.Separator();
string youName = _dalamudUtilService.GetPlayerName();
uint youWorld = _dalamudUtilService.GetWorldId();
ulong youCid = _dalamudUtilService.GetCID();
if (!selectedServer.Authentications.Exists(a => string.Equals(a.CharacterName, youName, StringComparison.Ordinal) && a.WorldId == youWorld))
{
_uiShared.BigText("Your Character is not Configured", ImGuiColors.DalamudRed);
UiSharedService.ColorTextWrapped("You have currently no character configured that corresponds to your current name and world.", ImGuiColors.DalamudRed);
var authWithCid = selectedServer.Authentications.Find(f => f.LastSeenCID == youCid);
if (authWithCid != null)
{
ImGuiHelpers.ScaledDummy(5);
UiSharedService.ColorText("A potential rename/world change from this character was detected:", ImGuiColors.DalamudYellow);
using (ImRaii.PushIndent(10f))
UiSharedService.ColorText("Entry: " + authWithCid.CharacterName + " - " + _dalamudUtilService.WorldData.Value[(ushort)authWithCid.WorldId], ImGuiColors.ParsedGreen);
UiSharedService.ColorText("Press the button below to adjust that entry to your current character:", ImGuiColors.DalamudYellow);
using (ImRaii.PushIndent(10f))
UiSharedService.ColorText("Current: " + youName + " - " + _dalamudUtilService.WorldData.Value[(ushort)youWorld], ImGuiColors.ParsedGreen);
ImGuiHelpers.ScaledDummy(5);
if (_uiShared.IconTextButton(FontAwesomeIcon.ArrowRight, "Update Entry to Current Character"))
{
authWithCid.CharacterName = youName;
authWithCid.WorldId = youWorld;
_serverConfigurationManager.Save();
}
}
ImGuiHelpers.ScaledDummy(5);
ImGui.Separator();
ImGuiHelpers.ScaledDummy(5);
}
foreach (var item in selectedServer.Authentications.ToList())
{
using var charaId = ImRaii.PushId("selectedChara" + i);
@@ -1463,8 +1496,6 @@ public class SettingsUi : WindowMediatorSubscriberBase
worldPreview = data.First().Value;
}
var friendlyName = string.Empty;
string friendlyNameTranslation = string.Empty;
Dictionary<int, SecretKey> keys = [];
if (!useOauth)
@@ -1475,19 +1506,11 @@ public class SettingsUi : WindowMediatorSubscriberBase
{
secretKey = new();
}
friendlyName = secretKey.FriendlyName;
friendlyNameTranslation = "Secret Key";
}
else
{
friendlyName = item.UID ?? "-";
friendlyNameTranslation = "UID";
}
bool thisIsYou = false;
if (string.Equals(_dalamudUtilService.GetPlayerName(), item.CharacterName, StringComparison.OrdinalIgnoreCase)
&& _dalamudUtilService.GetWorldId() == worldIdx)
if (string.Equals(youName, item.CharacterName, StringComparison.OrdinalIgnoreCase)
&& youWorld == worldIdx)
{
thisIsYou = true;
}
@@ -1500,61 +1523,84 @@ public class SettingsUi : WindowMediatorSubscriberBase
{
misManaged = true;
}
if (ImGui.TreeNode($"chara", (misManaged ? "[!! MISMANAGED !!] " : "") + (thisIsYou ? "[CURRENT] " : "") + $"Character: {item.CharacterName}, World: {worldPreview}, {friendlyNameTranslation}: {friendlyName}"))
Vector4 color = ImGuiColors.ParsedGreen;
string text = thisIsYou ? "Your Current Character" : string.Empty;
if (misManaged)
{
var charaName = item.CharacterName;
if (ImGui.InputText("Character Name", ref charaName, 64))
{
item.CharacterName = charaName;
_serverConfigurationManager.Save();
}
_uiShared.DrawCombo("World##" + item.CharacterName + i, data, (w) => w.Value,
(w) =>
{
if (item.WorldId != w.Key)
{
item.WorldId = w.Key;
_serverConfigurationManager.Save();
}
}, EqualityComparer<KeyValuePair<ushort, string>>.Default.Equals(data.FirstOrDefault(f => f.Key == worldIdx), default) ? data.First() : data.First(f => f.Key == worldIdx));
if (!useOauth)
{
_uiShared.DrawCombo("Secret Key###" + item.CharacterName + i, keys, (w) => w.Value.FriendlyName,
(w) =>
{
if (w.Key != item.SecretKeyIdx)
{
item.SecretKeyIdx = w.Key;
_serverConfigurationManager.Save();
}
}, EqualityComparer<KeyValuePair<int, SecretKey>>.Default.Equals(keys.FirstOrDefault(f => f.Key == item.SecretKeyIdx), default) ? keys.First() : keys.First(f => f.Key == item.SecretKeyIdx));
}
else
{
_uiShared.DrawUIDComboForAuthentication(i, item, selectedServer.ServerUri, _logger);
}
bool isAutoLogin = item.AutoLogin;
if (ImGui.Checkbox("Automatically login to Mare", ref isAutoLogin))
{
item.AutoLogin = isAutoLogin;
_serverConfigurationManager.Save();
}
_uiShared.DrawHelpText("When enabled and logging into this character in XIV, Mare will automatically connect to the current service.");
if (_uiShared.IconTextButton(FontAwesomeIcon.Trash, "Delete Character") && UiSharedService.CtrlPressed())
_serverConfigurationManager.RemoveCharacterFromServer(idx, item);
UiSharedService.AttachToolTip("Hold CTRL to delete this entry.");
ImGui.TreePop();
text += " [MISMANAGED (" + (selectedServer.UseOAuth2 ? "No UID Set" : "No Secret Key Set") + ")]";
color = ImGuiColors.DalamudRed;
}
if (selectedServer.Authentications.Where(e => e != item).Any(e => string.Equals(e.CharacterName, item.CharacterName, StringComparison.Ordinal)
&& e.WorldId == item.WorldId))
{
text += " [DUPLICATE]";
color = ImGuiColors.DalamudRed;
}
if (!string.IsNullOrEmpty(text))
{
text = text.Trim();
_uiShared.BigText(text, color);
}
var charaName = item.CharacterName;
if (ImGui.InputText("Character Name", ref charaName, 64))
{
item.CharacterName = charaName;
_serverConfigurationManager.Save();
}
_uiShared.DrawCombo("World##" + item.CharacterName + i, data, (w) => w.Value,
(w) =>
{
if (item.WorldId != w.Key)
{
item.WorldId = w.Key;
_serverConfigurationManager.Save();
}
}, EqualityComparer<KeyValuePair<ushort, string>>.Default.Equals(data.FirstOrDefault(f => f.Key == worldIdx), default) ? data.First() : data.First(f => f.Key == worldIdx));
if (!useOauth)
{
_uiShared.DrawCombo("Secret Key###" + item.CharacterName + i, keys, (w) => w.Value.FriendlyName,
(w) =>
{
if (w.Key != item.SecretKeyIdx)
{
item.SecretKeyIdx = w.Key;
_serverConfigurationManager.Save();
}
}, EqualityComparer<KeyValuePair<int, SecretKey>>.Default.Equals(keys.FirstOrDefault(f => f.Key == item.SecretKeyIdx), default) ? keys.First() : keys.First(f => f.Key == item.SecretKeyIdx));
}
else
{
_uiShared.DrawUIDComboForAuthentication(i, item, selectedServer.ServerUri, _logger);
}
bool isAutoLogin = item.AutoLogin;
if (ImGui.Checkbox("Automatically login to Mare", ref isAutoLogin))
{
item.AutoLogin = isAutoLogin;
_serverConfigurationManager.Save();
}
_uiShared.DrawHelpText("When enabled and logging into this character in XIV, Mare will automatically connect to the current service.");
if (_uiShared.IconTextButton(FontAwesomeIcon.Trash, "Delete Character") && UiSharedService.CtrlPressed())
_serverConfigurationManager.RemoveCharacterFromServer(idx, item);
UiSharedService.AttachToolTip("Hold CTRL to delete this entry.");
i++;
if (item != selectedServer.Authentications.ToList()[^1])
{
ImGuiHelpers.ScaledDummy(5);
ImGui.Separator();
ImGuiHelpers.ScaledDummy(5);
}
}
ImGui.Separator();
if (!selectedServer.Authentications.Exists(c => string.Equals(c.CharacterName, _uiShared.PlayerName, StringComparison.Ordinal)
&& c.WorldId == _uiShared.WorldId))
if (selectedServer.Authentications.Any())
ImGui.Separator();
if (!selectedServer.Authentications.Exists(c => string.Equals(c.CharacterName, youName, StringComparison.Ordinal)
&& c.WorldId == youWorld))
{
if (_uiShared.IconTextButton(FontAwesomeIcon.User, "Add current character"))
{
@@ -1624,7 +1670,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
ImGui.EndTabItem();
}
if (ImGui.BeginTabItem("Service Settings"))
if (ImGui.BeginTabItem("Service Configuration"))
{
var serverName = selectedServer.ServerName;
var serverUri = selectedServer.ServerUri;

View File

@@ -261,9 +261,9 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
Logger.LogError("Detected modified game files on connection");
if (!_mareConfigService.Current.DebugStopWhining)
Mediator.Publish(new NotificationMessage("Modified Game Files detected",
"Dalamud has reported modified game files in your FFXIV installation. " +
"You will be able to connect, but the synchronization functionality might be (partially) broken. " +
"Exit the game and repair it through XIVLauncher to get rid of this message.",
"Dalamud is reporting your FFXIV installation has modified game files. Mare Synchronos, Penumbra, and some other plugins assume your FFXIV installation " +
"is unmodified in order to work. Synchronization with pairs/shells can break because of this. Exit the game, open XIVLauncher, click the arrow next to Log " +
"In and select 'repair game files' to resolve this issue. Plugin configurations will remain, as will mods enabled in Penumbra.",
NotificationType.Error, TimeSpan.FromSeconds(15)));
}