- Use EndConditional

- Fix #132 (maybe)
This commit is contained in:
Infi
2024-11-21 13:59:45 +01:00
parent d0a55e80ea
commit 5bd6518e1a
4 changed files with 93 additions and 57 deletions
+8
View File
@@ -432,6 +432,14 @@ internal class UsedChannel
internal bool UseTempChannel; internal bool UseTempChannel;
internal InputChannel TempChannel = InputChannel.Invalid; internal InputChannel TempChannel = InputChannel.Invalid;
internal TellTarget? TempTellTarget;
internal void ResetTempChannel()
{
UseTempChannel = false;
TempTellTarget = null;
TempChannel = InputChannel.Invalid;
}
} }
[Serializable] [Serializable]
+2 -2
View File
@@ -258,7 +258,7 @@ internal sealed unsafe class Chat : IDisposable
{ {
Channel = (InputChannel) channel, Channel = (InputChannel) channel,
Name = nameChunks, Name = nameChunks,
TellTarget = playerName != null ? new TellTarget(playerName, worldId, 0, 0) : null, TellTarget = playerName != null ? new TellTarget(playerName, worldId, 0, 0) : null
}; };
return ret; return ret;
@@ -284,7 +284,7 @@ internal sealed unsafe class Chat : IDisposable
try try
{ {
var target = new TellTarget(playerName->ToString(), worldId, contentId, (TellReason) reason); var target = new TellTarget(playerName->ToString(), worldId, contentId, (TellReason) reason);
Plugin.ChatLogWindow.Activated(new ChatActivatedArgs(new ChannelSwitchInfo(InputChannel.Tell)) Plugin.ChatLogWindow.Activated(new ChatActivatedArgs(new ChannelSwitchInfo(InputChannel.Tell, permanent: setChatType))
{ {
TellReason = (TellReason) reason, TellReason = (TellReason) reason,
TellTarget = target, TellTarget = target,
+62 -54
View File
@@ -163,9 +163,7 @@ public sealed class ChatLogWindow : Window
var tellInfo = Plugin.Functions.Chat.GetTellHistoryInfo(idx); var tellInfo = Plugin.Functions.Chat.GetTellHistoryInfo(idx);
if (tellInfo != null && reason != null) if (tellInfo != null && reason != null)
{ Plugin.CurrentTab.CurrentChannel.TempTellTarget = new TellTarget(tellInfo.Name, (ushort) tellInfo.World, tellInfo.ContentId, reason.Value);
Plugin.CurrentTab.CurrentChannel.TellTarget = new TellTarget(tellInfo.Name, (ushort) tellInfo.World, tellInfo.ContentId, reason.Value);
}
} }
else else
{ {
@@ -630,8 +628,7 @@ public sealed class ChatLogWindow : Window
if (activeTab.CurrentChannel.UseTempChannel) if (activeTab.CurrentChannel.UseTempChannel)
{ {
activeTab.CurrentChannel.UseTempChannel = false; activeTab.CurrentChannel.ResetTempChannel();
activeTab.CurrentChannel.TempChannel = InputChannel.Invalid;
SetChannel(activeTab.CurrentChannel.Channel); SetChannel(activeTab.CurrentChannel.Channel);
} }
} }
@@ -643,8 +640,7 @@ public sealed class ChatLogWindow : Window
if (activeTab.CurrentChannel.UseTempChannel) if (activeTab.CurrentChannel.UseTempChannel)
{ {
activeTab.CurrentChannel.UseTempChannel = false; activeTab.CurrentChannel.ResetTempChannel();
activeTab.CurrentChannel.TempChannel = InputChannel.Invalid;
SetChannel(activeTab.CurrentChannel.Channel); SetChannel(activeTab.CurrentChannel.Channel);
} }
} }
@@ -666,10 +662,9 @@ public sealed class ChatLogWindow : Window
UIGlobals.PlaySoundEffect(ChatCloseSfx); UIGlobals.PlaySoundEffect(ChatCloseSfx);
} }
if (Plugin.CurrentTab.CurrentChannel.UseTempChannel) if (activeTab.CurrentChannel.UseTempChannel)
{ {
Plugin.CurrentTab.CurrentChannel.UseTempChannel = false; activeTab.CurrentChannel.ResetTempChannel();
activeTab.CurrentChannel.TempChannel = InputChannel.Invalid;
SetChannel(Plugin.CurrentTab.CurrentChannel.Channel); SetChannel(Plugin.CurrentTab.CurrentChannel.Channel);
} }
} }
@@ -763,50 +758,42 @@ public sealed class ChatLogWindow : Window
DrawChunks(currentChannel); DrawChunks(currentChannel);
} }
internal Chunk[] ReadChannelName(Tab activeTab) private Chunk[] ReadChannelName(Tab activeTab)
{ {
Chunk[] channelNameChunks; Chunk[] channelNameChunks;
if (activeTab.CurrentChannel.TellTarget != null && activeTab.CurrentChannel.TellTarget.IsSet()) // Check the temp channel before others
if (activeTab.CurrentChannel.UseTempChannel)
{ {
var playerName = activeTab.CurrentChannel.TellTarget.Name; if (activeTab.CurrentChannel.TempTellTarget != null && activeTab.CurrentChannel.TempTellTarget.IsSet())
if (ScreenshotMode)
// Note: don't use HidePlayerInString here because
// abbreviation settings do not affect this.
playerName = HashPlayer(activeTab.CurrentChannel.TellTarget.Name, activeTab.CurrentChannel.TellTarget.World);
var world = Sheets.WorldSheet.TryGetRow(activeTab.CurrentChannel.TellTarget.World, out var worldRow)
? worldRow.Name.ExtractText()
: "???";
channelNameChunks =
[
new TextChunk(ChunkSource.None, null, "Tell "),
new TextChunk(ChunkSource.None, null, playerName),
new IconChunk(ChunkSource.None, null, BitmapFontIcon.CrossWorld),
new TextChunk(ChunkSource.None, null, world)
];
}
else if (activeTab.CurrentChannel.UseTempChannel)
{
string name;
if (activeTab.CurrentChannel.TempChannel.IsLinkshell())
{ {
var idx = (uint) activeTab.CurrentChannel.TempChannel - (uint) InputChannel.Linkshell1; channelNameChunks = GenerateTellTargetName(activeTab.CurrentChannel.TempTellTarget);
var lsName = Plugin.Functions.Chat.GetLinkshellName(idx);
name = $"LS #{idx + 1}: {lsName}";
}
else if (activeTab.CurrentChannel.TempChannel.IsCrossLinkshell())
{
var idx = (uint) activeTab.CurrentChannel.TempChannel - (uint) InputChannel.CrossLinkshell1;
var cwlsName = Plugin.Functions.Chat.GetCrossLinkshellName(idx);
name = $"CWLS [{idx + 1}]: {cwlsName}";
} }
else else
{ {
name = activeTab.CurrentChannel.TempChannel.ToChatType().Name(); string name;
} if (activeTab.CurrentChannel.TempChannel.IsLinkshell())
{
var idx = (uint) activeTab.CurrentChannel.TempChannel - (uint) InputChannel.Linkshell1;
var lsName = Plugin.Functions.Chat.GetLinkshellName(idx);
name = $"LS #{idx + 1}: {lsName}";
}
else if (activeTab.CurrentChannel.TempChannel.IsCrossLinkshell())
{
var idx = (uint) activeTab.CurrentChannel.TempChannel - (uint) InputChannel.CrossLinkshell1;
var cwlsName = Plugin.Functions.Chat.GetCrossLinkshellName(idx);
name = $"CWLS [{idx + 1}]: {cwlsName}";
}
else
{
name = activeTab.CurrentChannel.TempChannel.ToChatType().Name();
}
channelNameChunks = [new TextChunk(ChunkSource.None, null, name)]; channelNameChunks = [new TextChunk(ChunkSource.None, null, name)];
}
}
else if (activeTab.CurrentChannel.TellTarget != null && activeTab.CurrentChannel.TellTarget.IsSet())
{
channelNameChunks = GenerateTellTargetName(activeTab.CurrentChannel.TellTarget);
} }
else if (activeTab is { Channel: { } channel }) else if (activeTab is { Channel: { } channel })
{ {
@@ -859,9 +846,11 @@ public sealed class ChatLogWindow : Window
internal void SetChannel(InputChannel? channel) internal void SetChannel(InputChannel? channel)
{ {
channel ??= InputChannel.Say; channel ??= InputChannel.Say;
if (channel != InputChannel.Tell) if (channel != InputChannel.Tell)
{
Plugin.CurrentTab.CurrentChannel.TellTarget = null; Plugin.CurrentTab.CurrentChannel.TellTarget = null;
Plugin.CurrentTab.CurrentChannel.TempTellTarget = null;
}
// Instead of calling SetChannel(), we ask the ExtraChat plugin to set a // Instead of calling SetChannel(), we ask the ExtraChat plugin to set a
// channel override by just calling the command directly. // channel override by just calling the command directly.
@@ -881,7 +870,29 @@ public sealed class ChatLogWindow : Window
return; return;
} }
Plugin.Functions.Chat.SetChannel(channel.Value, Plugin.CurrentTab.CurrentChannel.TellTarget); var target = Plugin.CurrentTab.CurrentChannel.TempTellTarget ?? Plugin.CurrentTab.CurrentChannel.TellTarget;
Plugin.Functions.Chat.SetChannel(channel.Value, target);
}
private Chunk[] GenerateTellTargetName(TellTarget tellTarget)
{
var playerName = tellTarget.Name;
if (ScreenshotMode)
// Note: don't use HidePlayerInString here because
// abbreviation settings do not affect this.
playerName = HashPlayer(tellTarget.Name, tellTarget.World);
var world = Sheets.WorldSheet.TryGetRow(tellTarget.World, out var worldRow)
? worldRow.Name.ExtractText()
: "???";
return
[
new TextChunk(ChunkSource.None, null, "Tell "),
new TextChunk(ChunkSource.None, null, playerName),
new IconChunk(ChunkSource.None, null, BitmapFontIcon.CrossWorld),
new TextChunk(ChunkSource.None, null, world)
];
} }
internal void SendChatBox(Tab activeTab) internal void SendChatBox(Tab activeTab)
@@ -900,10 +911,7 @@ public sealed class ChatLogWindow : Window
Plugin.Functions.Chat.SendTellUsingCommandInner(tellBytes); Plugin.Functions.Chat.SendTellUsingCommandInner(tellBytes);
TellSpecial = false; TellSpecial = false;
activeTab.CurrentChannel.UseTempChannel = false; activeTab.CurrentChannel.ResetTempChannel();
if (activeTab.CurrentChannel.TempChannel is InputChannel.Tell)
activeTab.CurrentChannel.TellTarget = null;
activeTab.CurrentChannel.TempChannel = InputChannel.Invalid;
Chat = string.Empty; Chat = string.Empty;
return; return;
@@ -911,7 +919,7 @@ public sealed class ChatLogWindow : Window
if (!trimmed.StartsWith('/')) if (!trimmed.StartsWith('/'))
{ {
var target = activeTab.CurrentChannel.TellTarget; var target = activeTab.CurrentChannel.TempTellTarget ?? activeTab.CurrentChannel.TellTarget;
if (target != null) if (target != null)
{ {
// ContentId 0 is a case where we can't directly send messages, so we send a /tell formatted message and let the game handle it // ContentId 0 is a case where we can't directly send messages, so we send a /tell formatted message and let the game handle it
@@ -941,7 +949,7 @@ public sealed class ChatLogWindow : Window
} }
if (activeTab.CurrentChannel.TempChannel is InputChannel.Tell) if (activeTab.CurrentChannel.TempChannel is InputChannel.Tell)
activeTab.CurrentChannel.TellTarget = null; activeTab.CurrentChannel.TempTellTarget = null;
Chat = string.Empty; Chat = string.Empty;
return; return;
+21 -1
View File
@@ -583,6 +583,26 @@ internal static class ImGuiUtil
} }
} }
// Use end-function only on success.
private struct EndConditionally(Action endAction, bool success) : ImRaii.IEndObject
{
public bool Success { get; } = success;
private bool Disposed { get; set; } = false;
private Action EndAction { get; } = endAction;
public void Dispose()
{
if (Disposed)
return;
if (Success)
EndAction();
Disposed = true;
}
}
public static ImRaii.IEndObject TextWrapPos() public static ImRaii.IEndObject TextWrapPos()
{ {
ImGui.PushTextWrapPos(); ImGui.PushTextWrapPos();
@@ -600,7 +620,7 @@ internal static class ImGuiUtil
public static ImRaii.IEndObject Menu(string label) public static ImRaii.IEndObject Menu(string label)
{ {
return new EndUnconditionally(ImGui.EndMenu, ImGui.BeginMenu(label)); return new EndConditionally(ImGui.EndMenu, ImGui.BeginMenu(label));
} }
public static void ChannelSelector(string headerText, Dictionary<ChatType, ChatSource> chatCodes) public static void ChannelSelector(string headerText, Dictionary<ChatType, ChatSource> chatCodes)