diff --git a/ChatTwo/ChatTwo.csproj b/ChatTwo/ChatTwo.csproj index 732e48a..d1bccab 100755 --- a/ChatTwo/ChatTwo.csproj +++ b/ChatTwo/ChatTwo.csproj @@ -1,6 +1,6 @@ - 1.28.2 + 1.29.0 net8.0-windows enable enable diff --git a/ChatTwo/GameFunctions/Chat.cs b/ChatTwo/GameFunctions/Chat.cs index 4bb4136..3420dc8 100755 --- a/ChatTwo/GameFunctions/Chat.cs +++ b/ChatTwo/GameFunctions/Chat.cs @@ -164,6 +164,9 @@ internal sealed unsafe class Chat : IDisposable return; ChangeChannelNameDetour(agent); + + // Inform all clients that a new login happend + Plugin.ServerCore.SendNewLogin(); } private byte ChatLogRefreshDetour(nint log, ushort eventId, AtkValue* value) diff --git a/ChatTwo/Http/HostContext.cs b/ChatTwo/Http/HostContext.cs index a3c3f5e..491d8e4 100644 --- a/ChatTwo/Http/HostContext.cs +++ b/ChatTwo/Http/HostContext.cs @@ -38,10 +38,12 @@ public class HostContext Host.Events.ExceptionEncountered += ExceptionEncountered; // Settings + #if DEBUG Host.Settings.Debug.Requests = true; Host.Settings.Debug.Routing = true; Host.Settings.Debug.Responses = true; Host.Settings.Debug.AccessControl = true; + #endif Host.Events.Logger = logMessage => Plugin.Log.Information(logMessage); IsActive = true; @@ -116,7 +118,6 @@ public class HostContext { await ctx.Response.Send("Nothing to see here."); } - #endregion private async Task CheckAuthenticationCookie(HttpContextBase ctx) { @@ -132,4 +133,5 @@ public class HostContext // Do nothing to let auth pass } + #endregion } \ No newline at end of file diff --git a/ChatTwo/Http/Processing.cs b/ChatTwo/Http/Processing.cs index 71b5271..030b920 100644 --- a/ChatTwo/Http/Processing.cs +++ b/ChatTwo/Http/Processing.cs @@ -50,7 +50,8 @@ public class Processing var channels = await Plugin.Framework.RunOnTick(Plugin.ChatLogWindow.GetAvailableChannels); var channelName = await Plugin.Framework.RunOnTick(() => ReadChannelName(Plugin.ChatLogWindow.PreviousChannel)); - sse.OutboundQueue.Enqueue(new NewMessageEvent(new Messages(messages))); + // Using the bulk message event to clear everything on the client side that may still exist + sse.OutboundQueue.Enqueue(new BulkMessagesEvent(new Messages(messages))); sse.OutboundQueue.Enqueue(new SwitchChannelEvent(new SwitchChannel(channelName))); sse.OutboundQueue.Enqueue(new ChannelListEvent(new ChannelList(channels.ToDictionary(pair => pair.Key, pair => (uint)pair.Value)))); } diff --git a/ChatTwo/Http/ServerCore.cs b/ChatTwo/Http/ServerCore.cs index 5f0218b..89a4d2b 100644 --- a/ChatTwo/Http/ServerCore.cs +++ b/ChatTwo/Http/ServerCore.cs @@ -92,6 +92,25 @@ public class ServerCore : IAsyncDisposable Plugin.Log.Error(ex, "Sending channel switch over SSE failed."); } } + + internal void SendNewLogin() + { + if (!HostContext.IsActive) + return; + + try + { + Plugin.Framework.RunOnTick(async () => + { + foreach (var eventServer in HostContext.EventConnections) + await HostContext.Processing.PrepareNewClient(eventServer); + }); + } + catch (Exception ex) + { + Plugin.Log.Error(ex, "Preparing all clients after login failed."); + } + } #endregion public void InvalidateSessions() diff --git a/ChatTwo/Plugin.cs b/ChatTwo/Plugin.cs index a456a85..31e7d3e 100755 --- a/ChatTwo/Plugin.cs +++ b/ChatTwo/Plugin.cs @@ -88,6 +88,9 @@ public sealed class Plugin : IDalamudPlugin ExtraChat = new ExtraChat(this); FontManager = new FontManager(); + // ChatLog calls this in its ctor if the player is already logged in + ServerCore = new ServerCore(this); + ChatLogWindow = new ChatLogWindow(this); SettingsWindow = new SettingsWindow(this); DbViewer = new DbViewer(this); @@ -130,8 +133,6 @@ public sealed class Plugin : IDalamudPlugin AutoTranslate.PreloadCache(); #endif - ServerCore = new ServerCore(this); - // Automatically start the webserver if requested if (Config.WebinterfaceAutoStart) { diff --git a/ChatTwo/Ui/ChatLogWindow.cs b/ChatTwo/Ui/ChatLogWindow.cs index f3443ba..2845b39 100644 --- a/ChatTwo/Ui/ChatLogWindow.cs +++ b/ChatTwo/Ui/ChatLogWindow.cs @@ -374,6 +374,10 @@ public sealed class ChatLogWindow : Window // If channel is null it doesn't have a default, and we never selected this channel before if (channel != null) SetChannel(tab.Channel ?? tab.PreviousChannel); + + // Inform the webinterface about tab switch + // TODO implement tabs in the webinterface + Plugin.ServerCore.SendNewLogin(); } internal static bool InBattle => Plugin.Condition[ConditionFlag.InCombat];