diff --git a/src/Nullinside.Api.Common/Twitch/ITwitchClientProxy.cs b/src/Nullinside.Api.Common/Twitch/ITwitchClientProxy.cs new file mode 100644 index 0000000..2d5958c --- /dev/null +++ b/src/Nullinside.Api.Common/Twitch/ITwitchClientProxy.cs @@ -0,0 +1,73 @@ +using TwitchLib.Client.Events; + +namespace Nullinside.Api.Common.Twitch; + +/// +/// Represents a twitch chat messaging client. +/// +public interface ITwitchClientProxy : IDisposable, IAsyncDisposable { + /// + /// Gets or sets the twitch username to connect with. + /// + string? TwitchUsername { get; set; } + + /// + /// Gets or sets the twitch OAuth token to use to connect. + /// + string? TwitchOAuthToken { get; set; } + + /// + /// Send a message in twitch chat. + /// + /// The channel to send the message in. + /// The message to send. + /// + /// The number of times to retry connecting to twitch chat before + /// giving up. + /// + /// True if connected and sent, false otherwise. + Task SendMessage(string channel, string message, uint retryConnection = 5); + + /// + /// Adds a callback for when the channel receives a new chat message. + /// + /// The name of the channel to add the callback for. + /// The callback to invoke. + /// An asynchronous task. + Task AddMessageCallback(string channel, Action callback); + + /// + /// Removes a callback for when the channel receives a new chat message. + /// + /// The callback to remove. + /// An asynchronous task. + void RemoveMessageCallback(Action callback); + + /// + /// Adds a callback for when users are banned from the chat. + /// + /// The channel to subscribe to notifications for. + /// The callback to invoke when a user is banned. + Task AddBannedCallback(string channel, Action callback); + + /// + /// Removes a callback for when users are banned from the chat. + /// + /// The callback to remove from when a user is banned. + void RemoveBannedCallback(Action callback); + + /// + /// Adds a callback for when the channel receives a raid. + /// + /// The channel to subscribe to callbacks for. + /// The callback to invoke. + /// An asynchronous task. + Task AddRaidCallback(string channel, Action callback); + + /// + /// Removes a callback for when the channel receives a raid. + /// + /// The callback to remove. + /// An asynchronous task. + void RemoveRaidCallback(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 f97b7da..a231007 100644 --- a/src/Nullinside.Api.Common/Twitch/TwitchClientProxy.cs +++ b/src/Nullinside.Api.Common/Twitch/TwitchClientProxy.cs @@ -16,9 +16,9 @@ namespace Nullinside.Api.Common.Twitch; using Timer = Timer; /// -/// The singleton of the Cathy bot that existing in chat for reading and sending twitch chat messages. +/// The singleton of a twitch chat messaging client. /// -public class TwitchClientProxy : IDisposable { +public class TwitchClientProxy : ITwitchClientProxy { /// /// The logger. /// @@ -29,12 +29,6 @@ public class TwitchClientProxy : IDisposable { /// private static TwitchClientProxy? instance; - /// - /// The lock to prevent mutual exclusion on - /// and callbacks. - /// - private readonly object callbackLock = new(); - /// /// The list of chats we attempted to join with the bot. /// @@ -105,34 +99,19 @@ public static TwitchClientProxy Instance { } } - /// - /// Gets or sets the twitch username to connect with. - /// + /// public string? TwitchUsername { get; set; } - /// - /// Gets or sets the twitch OAuth token to use to connect. - /// + /// public string? TwitchOAuthToken { get; set; } - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// + /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } - /// - /// Send a message in twitch chat. - /// - /// The channel to send the message in. - /// The message to send. - /// - /// The number of times to retry connecting to twitch chat before - /// giving up. - /// - /// True if connected and sent, false otherwise. + /// public async Task SendMessage(string channel, string message, uint retryConnection = 5) { // Sanity check. if (string.IsNullOrWhiteSpace(channel)) { @@ -174,6 +153,50 @@ public async Task SendMessage(string channel, string message, uint retryCo return true; } + /// + public async Task AddMessageCallback(string channel, Action callback) { + await JoinChannel(channel); + onMessageReceived -= callback; + onMessageReceived += callback; + } + + /// + public void RemoveMessageCallback(Action callback) { + onMessageReceived -= callback; + } + + /// + public async Task AddBannedCallback(string channel, Action callback) { + await JoinChannel(channel); + + onUserBanReceived -= callback; + onUserBanReceived += callback; + } + + /// + public void RemoveBannedCallback(Action callback) { + onUserBanReceived -= callback; + } + + /// + public async Task AddRaidCallback(string channel, Action callback) { + await JoinChannel(channel); + + onRaid -= callback; + onRaid += callback; + } + + /// + public void RemoveRaidCallback(Action callback) { + onRaid -= callback; + } + + /// + public ValueTask DisposeAsync() { + Dispose(); + return ValueTask.CompletedTask; + } + /// /// Joins a twitch channel. /// @@ -316,94 +339,13 @@ private async Task Connect() { }); } - /// - /// Adds a callback for when the channel receives a new chat message. - /// - /// The name of the channel to add the callback for. - /// The callback to invoke. - /// An asynchronous task. - public async Task AddMessageCallback(string channel, Action callback) { - await JoinChannel(channel); - - lock (callbackLock) { - onMessageReceived -= callback; - onMessageReceived += callback; - } - } - - /// - /// Removes a callback for when the channel receives a new chat message. - /// - /// The callback to remove. - /// An asynchronous task. - public void RemoveMessageCallback(Action callback) { - lock (callbackLock) { - onMessageReceived -= callback; - } - } - - /// - /// Adds a callback for when users are banned from the chat. - /// - /// The channel to subscribe to notifications for. - /// The callback to invoke when a user is banned. - public async Task AddBannedCallback(string channel, Action callback) { - await JoinChannel(channel); - - lock (callbackLock) { - onUserBanReceived -= callback; - onUserBanReceived += callback; - } - } - - /// - /// Removes a callback for when users are banned from the chat. - /// - /// The callback to remove from when a user is banned. - public void RemoveBannedCallback(Action callback) { - lock (callbackLock) { - onUserBanReceived -= callback; - } - } - - /// - /// Adds a callback for when the channel receives a raid. - /// - /// The channel to subscribe to callbacks for. - /// The callback to invoke. - /// An asynchronous task. - public async Task AddRaidCallback(string channel, Action callback) { - await JoinChannel(channel); - - lock (callbackLock) { - onRaid -= callback; - onRaid += callback; - } - } - - /// - /// Removes a callback for when the channel receives a raid. - /// - /// The callback to remove. - /// An asynchronous task. - public void RemoveRaidCallback(Action callback) { - lock (callbackLock) { - onRaid -= callback; - } - } - /// /// Handles when the channel receives a raid. /// /// The twitch client. /// The event arguments. private void TwitchChatClient_OnRaidNotification(object? sender, OnRaidNotificationArgs e) { - Delegate[]? invokeList = null; - - lock (callbackLock) { - invokeList = onRaid?.GetInvocationList(); - } - + Delegate[]? invokeList = onRaid?.GetInvocationList(); if (null == invokeList) { return; } @@ -419,12 +361,7 @@ private void TwitchChatClient_OnRaidNotification(object? sender, OnRaidNotificat /// The twitch client. /// The event arguments. private void TwitchChatClient_OnMessageReceived(object? sender, OnMessageReceivedArgs e) { - Delegate[]? invokeList = null; - - lock (callbackLock) { - invokeList = onMessageReceived?.GetInvocationList(); - } - + Delegate[]? invokeList = onMessageReceived?.GetInvocationList(); if (null == invokeList) { return; } @@ -434,13 +371,13 @@ private void TwitchChatClient_OnMessageReceived(object? sender, OnMessageReceive } } + /// + /// Handles when a channel receives a new ban. + /// + /// The twitch client. + /// The event arguments. private void TwitchChatClient_OnUserBanned(object? sender, OnUserBannedArgs e) { - Delegate[]? invokeList = null; - - lock (callbackLock) { - invokeList = onUserBanReceived?.GetInvocationList(); - } - + Delegate[]? invokeList = onUserBanReceived?.GetInvocationList(); if (null == invokeList) { return; }