diff --git a/src/Nullinside.Api.Common/Twitch/ITwitchClientProxy.cs b/src/Nullinside.Api.Common/Twitch/ITwitchClientProxy.cs
index 2d5958c..9d70354 100644
--- a/src/Nullinside.Api.Common/Twitch/ITwitchClientProxy.cs
+++ b/src/Nullinside.Api.Common/Twitch/ITwitchClientProxy.cs
@@ -39,9 +39,10 @@ public interface ITwitchClientProxy : IDisposable, IAsyncDisposable {
///
/// Removes a callback for when the channel receives a new chat message.
///
+ /// The name of the channel to add the callback for.
/// The callback to remove.
/// An asynchronous task.
- void RemoveMessageCallback(Action callback);
+ void RemoveMessageCallback(string channel, Action callback);
///
/// Adds a callback for when users are banned from the chat.
@@ -53,8 +54,9 @@ public interface ITwitchClientProxy : IDisposable, IAsyncDisposable {
///
/// Removes a callback for when users are banned from the chat.
///
+ /// The name of the channel to add the callback for.
/// The callback to remove from when a user is banned.
- void RemoveBannedCallback(Action callback);
+ void RemoveBannedCallback(string channel, Action callback);
///
/// Adds a callback for when the channel receives a raid.
@@ -67,7 +69,8 @@ public interface ITwitchClientProxy : IDisposable, IAsyncDisposable {
///
/// Removes a callback for when the channel receives a raid.
///
+ /// The name of the channel to add the callback for.
/// The callback to remove.
/// An asynchronous task.
- void RemoveRaidCallback(Action callback);
+ void RemoveRaidCallback(string channel, Action callback);
}
\ No newline at end of file
diff --git a/src/Nullinside.Api.Common/Twitch/TwitchClientProxy.cs b/src/Nullinside.Api.Common/Twitch/TwitchClientProxy.cs
index 2405138..426cde9 100644
--- a/src/Nullinside.Api.Common/Twitch/TwitchClientProxy.cs
+++ b/src/Nullinside.Api.Common/Twitch/TwitchClientProxy.cs
@@ -29,11 +29,6 @@ public class TwitchClientProxy : ITwitchClientProxy {
///
private static TwitchClientProxy? instance;
- ///
- /// The callback(s) to invoke when a new instance is created.
- ///
- private static Action? onInstanceCreated;
-
///
/// The list of chats we attempted to join with the bot.
///
@@ -61,17 +56,17 @@ public class TwitchClientProxy : ITwitchClientProxy {
///
/// The callback(s) to invoke when a channel receives a chat message.
///
- private Action? onMessageReceived;
+ private Dictionary?> _onMessageReceived = new();
///
/// The callback(s) to invoke when a channel is raided.
///
- private Action? onRaid;
+ private Dictionary?> onRaid = new();
///
/// The callback(s) to invoke when a channel receives a ban message.
///
- private Action? onUserBanReceived;
+ private Dictionary?> onUserBanReceived = new();
///
/// The web socket to connect to twitch chat with.
@@ -98,7 +93,6 @@ public static TwitchClientProxy Instance {
get {
if (null == instance) {
instance = new TwitchClientProxy();
- onInstanceCreated?.Invoke(instance);
}
return instance;
@@ -162,39 +156,60 @@ public async Task SendMessage(string channel, string message, uint retryCo
///
public async Task AddMessageCallback(string channel, Action callback) {
await JoinChannel(channel);
- onMessageReceived -= callback;
- onMessageReceived += callback;
+ var channelSan = channel.ToLowerInvariant();
+ lock (_onMessageReceived) {
+ _onMessageReceived[channelSan] = callback;
+ }
}
///
- public void RemoveMessageCallback(Action callback) {
- onMessageReceived -= callback;
+ public void RemoveMessageCallback(string channel, Action callback) {
+ bool shouldRemove = false;
+ var channelSan = channel.ToLowerInvariant();
+ lock (_onMessageReceived) {
+ _onMessageReceived.Remove(channel);
+ }
+
+ if (shouldRemove) {
+ client?.LeaveChannel(channelSan);
+
+ // First add the channel to the master list.
+ lock (joinedChannels) {
+ joinedChannels.Add(channelSan);
+ }
+ }
}
///
public async Task AddBannedCallback(string channel, Action callback) {
await JoinChannel(channel);
- onUserBanReceived -= callback;
- onUserBanReceived += callback;
+ lock (onUserBanReceived) {
+ onUserBanReceived[channel] = callback;
+ }
}
///
- public void RemoveBannedCallback(Action callback) {
- onUserBanReceived -= callback;
+ public void RemoveBannedCallback(string channel, Action callback) {
+ lock (onUserBanReceived) {
+ onUserBanReceived.Remove(channel);
+ }
}
///
public async Task AddRaidCallback(string channel, Action callback) {
await JoinChannel(channel);
- onRaid -= callback;
- onRaid += callback;
+ lock (onRaid) {
+ onRaid[channel] = callback;
+ }
}
///
- public void RemoveRaidCallback(Action callback) {
- onRaid -= callback;
+ public void RemoveRaidCallback(string channel, Action callback) {
+ lock (onRaid) {
+ onRaid.Remove(channel);
+ }
}
///
@@ -203,17 +218,6 @@ public ValueTask DisposeAsync() {
return ValueTask.CompletedTask;
}
- ///
- public void AddInstanceCallback(Action callback) {
- onInstanceCreated -= callback;
- onInstanceCreated += callback;
- }
-
- ///
- public void RemoveInstanceCallback(Action callback) {
- onInstanceCreated -= callback;
- }
-
///
/// Joins a twitch channel.
///
@@ -303,6 +307,10 @@ private async Task Connect() {
try {
bool isConnected = false;
lock (twitchClientLock) {
+ if (client?.IsConnected ?? false) {
+ return true;
+ }
+
// If this is a first time initialization, create a brand-new client.
bool haveNoClient = null == client;
if (haveNoClient) {
@@ -377,7 +385,13 @@ private async Task Connect() {
/// The twitch client.
/// The event arguments.
private void TwitchChatClient_OnRaidNotification(object? sender, OnRaidNotificationArgs e) {
- Delegate[]? invokeList = onRaid?.GetInvocationList();
+ Action? callback;
+ var channel = e.Channel.ToLowerInvariant();
+ lock (onRaid) {
+ onRaid.TryGetValue(channel, out callback);
+ }
+
+ Delegate[]? invokeList = callback?.GetInvocationList();
if (null == invokeList) {
return;
}
@@ -393,7 +407,19 @@ private void TwitchChatClient_OnRaidNotification(object? sender, OnRaidNotificat
/// The twitch client.
/// The event arguments.
private void TwitchChatClient_OnMessageReceived(object? sender, OnMessageReceivedArgs e) {
- Delegate[]? invokeList = onMessageReceived?.GetInvocationList();
+ Action? callbacks = null;
+ var channelSan = e.ChatMessage.Channel.ToLowerInvariant();
+ lock (_onMessageReceived) {
+ if (_onMessageReceived.TryGetValue(channelSan, out Action? messageReceivedCallback)) {
+ callbacks = messageReceivedCallback;
+ }
+ }
+
+ if (null == callbacks) {
+ return;
+ }
+
+ Delegate[]? invokeList = callbacks?.GetInvocationList();
if (null == invokeList) {
return;
}
@@ -409,7 +435,13 @@ private void TwitchChatClient_OnMessageReceived(object? sender, OnMessageReceive
/// The twitch client.
/// The event arguments.
private void TwitchChatClient_OnUserBanned(object? sender, OnUserBannedArgs e) {
- Delegate[]? invokeList = onUserBanReceived?.GetInvocationList();
+ Action? callback;
+ var channel = e.UserBan.Channel.ToLowerInvariant();
+ lock (onUserBanReceived) {
+ onUserBanReceived.TryGetValue(channel, out callback);
+ }
+
+ Delegate[]? invokeList = callback?.GetInvocationList();
if (null == invokeList) {
return;
}