Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reconnecting to Twitch chat #537

Merged
merged 1 commit into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/TrackerCouncil.Smz3.Chat.Integration/IChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public interface IChatClient : IDisposable
{
event EventHandler? Connected;

event EventHandler? Reconnected;

event EventHandler? Disconnected;

event EventHandler? SendMessageFailure;
Expand Down
36 changes: 35 additions & 1 deletion src/TrackerCouncil.Smz3.Chat.Twitch/TwitchChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using TrackerCouncil.Smz3.Chat.Integration.Models;
using TrackerCouncil.Smz3.Chat.Twitch.Models;
using TwitchLib.Client;
using TwitchLib.Client.Events;
using TwitchLib.Client.Exceptions;
using TwitchLib.Client.Models;

Expand All @@ -17,6 +18,7 @@ public class TwitchChatClient : IChatClient
{
private readonly TwitchClient _twitchClient;
private readonly IChatApi _chatApi;
private bool _firstConnection = true;

public TwitchChatClient(ILogger<TwitchChatClient> logger, ILoggerFactory loggerFactory, IChatApi chatApi)
{
Expand All @@ -25,13 +27,17 @@ public TwitchChatClient(ILogger<TwitchChatClient> logger, ILoggerFactory loggerF
_twitchClient.OnConnected += _twitchClient_OnConnected;
_twitchClient.OnDisconnected += _twitchClient_OnDisconnected;
_twitchClient.OnMessageReceived += _twitchClient_OnMessageReceived;
_twitchClient.OnReconnected += _twitchClient_OnReconnected;
_twitchClient.OnJoinedChannel += _twitchClient_OnJoinedChannel;
_chatApi = chatApi;
}

public event EventHandler? Connected;

public event EventHandler? Disconnected;

public event EventHandler? Reconnected;

public event EventHandler? SendMessageFailure;

public event MessageReceivedEventHandler? MessageReceived;
Expand Down Expand Up @@ -109,6 +115,11 @@ protected virtual void OnConnected()
Connected?.Invoke(this, new());
}

protected virtual void OnReconnected()
{
Reconnected?.Invoke(this, new());
}

protected virtual void OnDisconnected()
{
Logger.LogWarning("Connection to chat lost");
Expand All @@ -131,7 +142,6 @@ protected virtual void Dispose(bool disposing)
private void _twitchClient_OnConnected(object? sender, TwitchLib.Client.Events.OnConnectedArgs e)
{
IsConnected = true;
OnConnected();
}

private void _twitchClient_OnDisconnected(object? sender, TwitchLib.Communication.Events.OnDisconnectedEventArgs e)
Expand All @@ -148,6 +158,30 @@ private void _twitchClient_OnMessageReceived(object? sender, TwitchLib.Client.Ev
OnMessageReceived(new MessageReceivedEventArgs(new TwitchChatMessage(e.ChatMessage)));
}

private void _twitchClient_OnReconnected(object? sender, TwitchLib.Communication.Events.OnReconnectedEventArgs e)
{
// Unfortunately this fires before reconnecting is genuinely finished, so we have to wait before
// rejoining the original channel
Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(3));
_twitchClient.JoinChannel(Channel);
});
}

private void _twitchClient_OnJoinedChannel(object? sender, OnJoinedChannelArgs e)
{
if (_firstConnection)
{
OnConnected();
_firstConnection = false;
}
else
{
OnReconnected();
}
}

public async Task<string?> CreatePollAsync(string title, ICollection<string> options, int duration)
{
// Create the poll object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public class ChatConfig : IMergeable<ChatConfig>
/// </summary>
public SchrodingersString? WhenConnected { get; init; }

/// <summary>
/// Gets the phrases to respond with when reconnected to chat.
/// </summary>
public SchrodingersString? WhenReconnected { get; init; }

/// <summary>
/// Gets the phrases to respond with when disconnected to chat.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public ChatIntegrationModule(TrackerBase tracker, IChatClient chatClient, IItemS
_itemService = itemService;
_timerService = timerService;
ChatClient.Connected += ChatClient_Connected;
ChatClient.Reconnected += ChatClient_Reconnected;
ChatClient.MessageReceived += ChatClient_MessageReceived;
ChatClient.Disconnected += ChatClient_Disconnected;
ChatClient.SendMessageFailure += ChatClient_SendMessageFailure;
Expand Down Expand Up @@ -500,6 +501,11 @@ private void ChatClient_Disconnected(object? sender, EventArgs e)
TrackerBase.Say(x => x.Chat.WhenDisconnected);
}

private void ChatClient_Reconnected(object? sender, EventArgs e)
{
TrackerBase.Say(x => x.Chat.WhenReconnected);
}

private void ChatClient_SendMessageFailure(object? sender, EventArgs e)
{
TrackerBase.Error();
Expand Down