diff --git a/KitchenSink/Commands/CharacterSwitch.cs b/KitchenSink/Commands/CharacterSwitch.cs index 605793a..a0d60be 100644 --- a/KitchenSink/Commands/CharacterSwitch.cs +++ b/KitchenSink/Commands/CharacterSwitch.cs @@ -8,6 +8,7 @@ using Dalamud.Game.Command; using Dalamud.Game.Gui.Dtr; using Dalamud.Game.Text; using Dalamud.Interface.ImGuiNotification; +using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.UI; @@ -76,34 +77,42 @@ internal sealed class CharacterSwitch : IDisposable private Target? FindCharacter(int direction, bool showError = true) { - _pluginLog.Verbose($"Switching characters ({direction})"); - - var characterIds = _autoRetainerApi.GetRegisteredCharacters(); - int index = characterIds.IndexOf(_clientState.LocalContentId); - if (index < 0) + try { - if (showError) - _chatGui.PrintError("[KitchenSink] Current character not known."); - return null; - } + _pluginLog.Verbose($"Switching characters ({direction})"); - OfflineCharacterData? target; - do - { - index = (index + direction + characterIds.Count) % characterIds.Count; - target = _autoRetainerApi.GetOfflineCharacterData(characterIds[index]); - if (target?.CID == _clientState.LocalContentId) + var characterIds = _autoRetainerApi.GetRegisteredCharacters(); + int index = characterIds.IndexOf(_clientState.LocalContentId); + if (index < 0) { if (showError) - _chatGui.PrintError("[KitchenSink] No character to switch to found."); + _chatGui.PrintError("[KitchenSink] Current character not known."); return null; } - if (target is { ExcludeRetainer: true, ExcludeWorkshop: true }) - target = null; - } while (target == null); + OfflineCharacterData? target; + do + { + index = (index + direction + characterIds.Count) % characterIds.Count; + target = _autoRetainerApi.GetOfflineCharacterData(characterIds[index]); + if (target?.CID == _clientState.LocalContentId) + { + if (showError) + _chatGui.PrintError("[KitchenSink] No character to switch to found."); + return null; + } - return new Target(target.Name, target.World); + if (target is { ExcludeRetainer: true, ExcludeWorkshop: true }) + target = null; + } while (target == null); + + return new Target(target.Name, target.World); + } + catch (IpcError) + { + _chatGui.PrintError("Could not switch character, AutoRetainer API isn't available."); + return null; + } } private void NextCharacter(string command, string arguments) => SwitchCharacter(FindCharacter(1)); @@ -118,26 +127,34 @@ internal sealed class CharacterSwitch : IDisposable return; } - string[] args = arguments.Split(' ', 2); - if (args.Length < 2 || !int.TryParse(args[1], CultureInfo.InvariantCulture, out int index)) - index = 1; - - var targets = _autoRetainerApi.GetRegisteredCharacters() - .Select(characterId => _autoRetainerApi.GetOfflineCharacterData(characterId)) - .Where(x => !x.ExcludeRetainer || !x.ExcludeWorkshop) - .Select(x => new { x.Name, x.World }) - .ToList(); - var target = targets.Where(x => x.World.StartsWith(args[0], StringComparison.OrdinalIgnoreCase)).Skip(index - 1) - .FirstOrDefault() ?? - targets.FirstOrDefault(x => x.Name.Contains(arguments, StringComparison.OrdinalIgnoreCase)); - - if (target == null) + try { - _chatGui.PrintError($"[KitchenSink] No character found on world {args[0]} with #{index}."); - return; - } + string[] args = arguments.Split(' ', 2); + if (args.Length < 2 || !int.TryParse(args[1], CultureInfo.InvariantCulture, out int index)) + index = 1; - SwitchCharacter(new Target(target.Name, target.World)); + var targets = _autoRetainerApi.GetRegisteredCharacters() + .Select(characterId => _autoRetainerApi.GetOfflineCharacterData(characterId)) + .Where(x => !x.ExcludeRetainer || !x.ExcludeWorkshop) + .Select(x => new { x.Name, x.World }) + .ToList(); + var target = targets.Where(x => x.World.StartsWith(args[0], StringComparison.OrdinalIgnoreCase)) + .Skip(index - 1) + .FirstOrDefault() ?? + targets.FirstOrDefault(x => x.Name.Contains(arguments, StringComparison.OrdinalIgnoreCase)); + + if (target == null) + { + _chatGui.PrintError($"[KitchenSink] No character found on world {args[0]} with #{index}."); + return; + } + + SwitchCharacter(new Target(target.Name, target.World)); + } + catch (IpcError) + { + _chatGui.PrintError("Could not switch character, AutoRetainer API isn't available."); + } } private void SwitchCharacter(Target? target) @@ -174,32 +191,45 @@ internal sealed class CharacterSwitch : IDisposable private void UpdateDtrBar() { - string? currentWorld = _clientState.LocalPlayer?.CurrentWorld.GameData?.Name?.ToString(); - string? homeWorld = _clientState.LocalPlayer?.HomeWorld.GameData?.Name?.ToString(); - var characterIds = _autoRetainerApi.GetRegisteredCharacters() ?? new(); - var characterIdsOnHomeWorld = characterIds - .Where(x => _autoRetainerApi.GetOfflineCharacterData(x)?.World == homeWorld).ToList(); + if (_dtrBarEntry.UserHidden) + return; - SeIconChar seIconChar = SeIconChar.Instance1 + characterIdsOnHomeWorld.IndexOf(_clientState.LocalContentId); - if (currentWorld == homeWorld) + try { - _dtrBarEntry.Text = seIconChar.ToIconString(); + string? currentWorld = _clientState.LocalPlayer?.CurrentWorld.GameData?.Name?.ToString(); + string? homeWorld = _clientState.LocalPlayer?.HomeWorld.GameData?.Name?.ToString(); + var characterIds = _autoRetainerApi.GetRegisteredCharacters() ?? new(); + var characterIdsOnHomeWorld = characterIds + .Where(x => _autoRetainerApi.GetOfflineCharacterData(x)?.World == homeWorld).ToList(); - var previous = FindCharacter(-1, showError: false); - var next = FindCharacter(1, showError: false); - if (previous != null && next != null) - _dtrBarEntry.Tooltip = $"Prev: {previous.ToString(homeWorld)}\nNext: {next.ToString(homeWorld)}"; - else if (previous != null) - _dtrBarEntry.Tooltip = $"Prev: {previous.ToString(homeWorld)}"; - else if (next != null) - _dtrBarEntry.Tooltip = $"Next: {next.ToString(homeWorld)}"; + SeIconChar seIconChar = SeIconChar.Instance1 + characterIdsOnHomeWorld.IndexOf(_clientState.LocalContentId); + if (currentWorld == homeWorld) + { + _dtrBarEntry.Text = seIconChar.ToIconString(); + + var previous = FindCharacter(-1, showError: false); + var next = FindCharacter(1, showError: false); + if (previous != null && next != null) + _dtrBarEntry.Tooltip = $"Prev: {previous.ToString(homeWorld)}\nNext: {next.ToString(homeWorld)}"; + else if (previous != null) + _dtrBarEntry.Tooltip = $"Prev: {previous.ToString(homeWorld)}"; + else if (next != null) + _dtrBarEntry.Tooltip = $"Next: {next.ToString(homeWorld)}"; + else + _dtrBarEntry.Tooltip = null; + } else - _dtrBarEntry.Tooltip = null; + { + _dtrBarEntry.Text = $"{homeWorld} {seIconChar.ToIconString()}"; + _dtrBarEntry.Tooltip = $"Return to {homeWorld}"; + } + + if (!_dtrBarEntry.Shown) + _dtrBarEntry.Shown = true; } - else + catch (IpcError) { - _dtrBarEntry.Text = $"{homeWorld} {seIconChar.ToIconString()}"; - _dtrBarEntry.Tooltip = $"Return to {homeWorld}"; + _dtrBarEntry.Shown = false; } }