diff --git a/Chat/Commands/Limits/UsagePolicy.cs b/Chat/Commands/Limits/UsagePolicy.cs index 309890e..edffb55 100644 --- a/Chat/Commands/Limits/UsagePolicy.cs +++ b/Chat/Commands/Limits/UsagePolicy.cs @@ -229,6 +229,7 @@ namespace TwitchChatTTS.Chat.Commands.Limits var temp = usage.Uses.Skip(sizeDiff); var tempSize = usage.Uses.Length - sizeDiff; usage.Uses = temp.Union(new DateTime[Math.Max(0, Limit.Count - tempSize)]).ToArray(); + } finally { _rwls.ExitWriteLock(); @@ -256,7 +257,7 @@ namespace TwitchChatTTS.Chat.Commands.Limits } finally { - _rwls.ExitWriteLock(); + _rwls.ExitUpgradeableReadLock(); } return true; diff --git a/Chat/Groups/ChatterGroupManager.cs b/Chat/Groups/ChatterGroupManager.cs index cce52b3..c3c5f24 100644 --- a/Chat/Groups/ChatterGroupManager.cs +++ b/Chat/Groups/ChatterGroupManager.cs @@ -1,5 +1,3 @@ - -using System.Collections.Concurrent; using HermesSocketLibrary.Requests.Messages; using Serilog; @@ -9,109 +7,199 @@ namespace TwitchChatTTS.Chat.Groups { private readonly IDictionary _groups; private readonly IDictionary> _chatters; + private readonly ReaderWriterLockSlim _rwls; private readonly ILogger _logger; public ChatterGroupManager(ILogger logger) { _logger = logger; - _groups = new ConcurrentDictionary(); - _chatters = new ConcurrentDictionary>(); + _groups = new Dictionary(); + _chatters = new Dictionary>(); + _rwls = new ReaderWriterLockSlim(); } public void Add(Group group) { - _groups.Add(group.Id, group); + _rwls.EnterWriteLock(); + try + { + _groups.Add(group.Id, group); + } + finally + { + _rwls.ExitWriteLock(); + } } public void Add(long chatterId, string groupId) { - if (_chatters.TryGetValue(chatterId, out var list)) + _rwls.EnterWriteLock(); + try { - if (!list.Contains(groupId)) - list.Add(groupId); + if (_chatters.TryGetValue(chatterId, out var list)) + { + if (!list.Contains(groupId)) + list.Add(groupId); + } + else + _chatters.Add(chatterId, new List() { groupId }); + } + finally + { + _rwls.ExitWriteLock(); } - else - _chatters.Add(chatterId, new List() { groupId }); } public void Add(long chatter, ICollection groupIds) { - if (_chatters.TryGetValue(chatter, out var list)) + _rwls.EnterWriteLock(); + try { - foreach (var groupId in groupIds) - if (!list.Contains(groupId)) - list.Add(groupId); + if (_chatters.TryGetValue(chatter, out var list)) + { + foreach (var groupId in groupIds) + if (!list.Contains(groupId)) + list.Add(groupId); + } + else + _chatters.Add(chatter, groupIds); + } + finally + { + _rwls.ExitWriteLock(); } - else - _chatters.Add(chatter, groupIds); } public void Clear() { - _groups.Clear(); - _chatters.Clear(); + _rwls.EnterWriteLock(); + try + { + _groups.Clear(); + _chatters.Clear(); + } + finally + { + _rwls.ExitWriteLock(); + } } public Group? Get(string groupId) { - if (_groups.TryGetValue(groupId, out var group)) - return group; - return null; + _rwls.EnterReadLock(); + try + { + if (_groups.TryGetValue(groupId, out var group)) + return group; + return null; + } + finally + { + _rwls.ExitReadLock(); + } } public IEnumerable GetGroupNamesFor(long chatter) { - if (_chatters.TryGetValue(chatter, out var groups)) - return groups.Select(g => _groups.TryGetValue(g, out var group) ? group.Name : null) - .Where(g => g != null) - .Cast(); + _rwls.EnterReadLock(); + try + { + if (_chatters.TryGetValue(chatter, out var groups)) + return groups.Select(g => _groups.TryGetValue(g, out var group) ? group.Name : null) + .Where(g => g != null) + .Cast(); - return Array.Empty(); + return Array.Empty(); + } + finally + { + _rwls.ExitReadLock(); + } } public int GetPriorityFor(long chatter) { - if (!_chatters.TryGetValue(chatter, out var groups)) - return 0; + _rwls.EnterReadLock(); + try + { + if (!_chatters.TryGetValue(chatter, out var groups)) + return 0; - return GetPriorityFor(groups); + return GetPriorityFor(groups); + } + finally + { + _rwls.ExitReadLock(); + } } public int GetPriorityFor(IEnumerable groupIds) { - var values = groupIds.Select(g => _groups.TryGetValue(g, out var group) ? group : null).Where(g => g != null); - if (values.Any()) - return values.Max(g => g!.Priority); - return 0; + _rwls.EnterReadLock(); + try + { + var values = groupIds.Select(g => _groups.TryGetValue(g, out var group) ? group : null).Where(g => g != null); + if (values.Any()) + return values.Max(g => g!.Priority); + return 0; + } + finally + { + _rwls.ExitReadLock(); + } } public void Modify(Group group) { - _groups[group.Id] = group; + _rwls.EnterWriteLock(); + try + { + _groups[group.Id] = group; + } + finally + { + _rwls.ExitWriteLock(); + } } public bool Remove(string groupId) { - if (_groups.Remove(groupId)) + _rwls.EnterWriteLock(); + try { - foreach (var entry in _chatters) - entry.Value.Remove(groupId); - return true; + if (_groups.Remove(groupId)) + { + foreach (var entry in _chatters) + entry.Value.Remove(groupId); + return true; + } + return false; + } + finally + { + _rwls.ExitReadLock(); } - return false; } public bool Remove(long chatterId, string groupId) { - if (_chatters.TryGetValue(chatterId, out var groups)) + _rwls.EnterWriteLock(); + try { - groups.Remove(groupId); - _logger.Debug($"Removed chatter from group [chatter id: {chatterId}][group name: {_groups[groupId].Name}][group id: {groupId}]"); - return true; + if (_chatters.TryGetValue(chatterId, out var groups)) + { + groups.Remove(groupId); + _logger.Debug($"Removed chatter from group [chatter id: {chatterId}][group name: {_groups[groupId].Name}][group id: {groupId}]"); + return true; + } + _logger.Debug($"Failed to remove chatter from group [chatter id: {chatterId}][group name: {_groups[groupId].Name}][group id: {groupId}]"); + return false; + } + finally + { + _rwls.ExitReadLock(); } - _logger.Debug($"Failed to remove chatter from group [chatter id: {chatterId}][group name: {_groups[groupId].Name}][group id: {groupId}]"); - return false; } } } \ No newline at end of file diff --git a/Chat/Groups/Permissions/GroupPermissionManager.cs b/Chat/Groups/Permissions/GroupPermissionManager.cs index bf969f0..3fe3d93 100644 --- a/Chat/Groups/Permissions/GroupPermissionManager.cs +++ b/Chat/Groups/Permissions/GroupPermissionManager.cs @@ -5,33 +5,51 @@ namespace TwitchChatTTS.Chat.Groups.Permissions { public class GroupPermissionManager : IGroupPermissionManager { - private PermissionNode _root; - private ILogger _logger; + private readonly PermissionNode _root; + private readonly ILogger _logger; + private readonly ReaderWriterLockSlim _rwls; public GroupPermissionManager(ILogger logger) { _logger = logger; _root = new PermissionNode(string.Empty, null, null); + _rwls = new ReaderWriterLockSlim(); } public bool? CheckIfAllowed(string path) { - var res = Get(path)!.Allow; - _logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"}"); - return res; + _rwls.EnterReadLock(); + try + { + var res = Get(path)!.Allow; + _logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"}"); + return res; + } + finally + { + _rwls.ExitReadLock(); + } } public bool? CheckIfDirectAllowed(string path) { - var node = Get(path, nullIfMissing: true); - if (node == null) - return null; - - var res = node.DirectAllow; - _logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"} [direct]"); - return res; + _rwls.EnterReadLock(); + try + { + var node = Get(path, nullIfMissing: true); + if (node == null) + return null; + + var res = node.DirectAllow; + _logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"} [direct]"); + return res; + } + finally + { + _rwls.ExitReadLock(); + } } public bool? CheckIfAllowed(IEnumerable groups, string path) @@ -64,31 +82,63 @@ namespace TwitchChatTTS.Chat.Groups.Permissions public void Clear() { - _root.Clear(); + _rwls.EnterWriteLock(); + try + { + _root.Clear(); + } + finally + { + _rwls.ExitWriteLock(); + } } public bool Remove(string path) { - var node = Get(path); - if (node == null || node.Parent == null) - return false; - - var parts = path.Split('.'); - var last = parts.Last(); - if (parts.Length > 1 && parts[parts.Length - 1] == node.Parent.Name || parts.Length == 1 && node.Parent.Name == null) + _rwls.EnterUpgradeableReadLock(); + try { - node.Parent.Remove(last); - _logger.Debug($"Permission Node REMOVE priv {path}"); - return true; + var node = Get(path); + if (node == null || node.Parent == null) + return false; + + _rwls.EnterWriteLock(); + try + { + var parts = path.Split('.'); + var last = parts.Last(); + if (parts.Length > 1 && parts[parts.Length - 1] == node.Parent.Name || parts.Length == 1 && node.Parent.Name == null) + { + node.Parent.Remove(last); + _logger.Debug($"Permission Node REMOVE priv {path}"); + return true; + } + return false; + } + finally + { + _rwls.ExitWriteLock(); + } + } + finally + { + _rwls.ExitUpgradeableReadLock(); } - return false; } public void Set(string path, bool? allow) { - var node = Get(path, true); - node!.Allow = allow; - _logger.Debug($"Permission Node ADD {path} = {allow?.ToString() ?? "null"}"); + _rwls.EnterWriteLock(); + try + { + var node = Get(path, true); + node!.Allow = allow; + _logger.Debug($"Permission Node ADD {path} = {allow?.ToString() ?? "null"}"); + } + finally + { + _rwls.ExitWriteLock(); + } } private PermissionNode? Get(string path, bool edit = false, bool nullIfMissing = false) diff --git a/Chat/Messaging/ChatMessageReader.cs b/Chat/Messaging/ChatMessageReader.cs index ba7719b..2246335 100644 --- a/Chat/Messaging/ChatMessageReader.cs +++ b/Chat/Messaging/ChatMessageReader.cs @@ -62,15 +62,15 @@ namespace TwitchChatTTS.Chat.Messaging var emoteUsage = GetEmoteUsage(fragments); var tasks = new List(); - if (_obs.Streaming && !_user.Slave) + if ((!_obs.Connected || _obs.Streaming) && !_user.Slave) { if (emoteUsage.NewEmotes.Any()) tasks.Add(_hermes.SendEmoteDetails(emoteUsage.NewEmotes)); if (emoteUsage.EmotesUsed.Any() && messageId != null && chatterId != null) tasks.Add(_hermes.SendEmoteUsage(messageId, chatterId.Value, emoteUsage.EmotesUsed)); - if (!string.IsNullOrEmpty(chatterLogin) && chatterId != null && !_user.Chatters.Contains(chatterId.Value)) + if (chatterId.HasValue && !_user.Chatters.Contains(chatterId.Value)) { - tasks.Add(_hermes.SendChatterDetails(chatterId.Value, chatterLogin)); + tasks.Add(_hermes.SendChatterDetails(chatterId.Value, chatterLogin!)); _user.Chatters.Add(chatterId.Value); } } diff --git a/Hermes/Socket/Handlers/LoginAckHandler.cs b/Hermes/Socket/Handlers/LoginAckHandler.cs index cd294b4..85942f0 100644 --- a/Hermes/Socket/Handlers/LoginAckHandler.cs +++ b/Hermes/Socket/Handlers/LoginAckHandler.cs @@ -33,8 +33,7 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers if (message.AnotherClient) { - if (client.LoggedIn) - _logger.Warning($"Another client has connected to the same account via {(message.WebLogin ? "web login" : "application")}."); + _logger.Warning($"Another client has connected to the same account via {(message.WebLogin ? "web login" : "application")}."); return; } if (client.LoggedIn) @@ -51,6 +50,7 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers _user.TwitchUsername = message.UserName; _user.TwitchUserId = long.Parse(message.ProviderAccountId); _user.OwnerId = message.OwnerId; + _user.StreamElementsOverlayKey = message.StreamElementsOverlayKey; _user.DefaultTTSVoice = message.DefaultTTSVoice; _user.VoicesAvailable = new ConcurrentDictionary(message.TTSVoicesAvailable); _user.VoicesEnabled = new HashSet(message.EnabledTTSVoices); @@ -58,7 +58,7 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers _user.NightbotConnection = message.Connections.FirstOrDefault(c => c.Default && c.Type == "nightbot") ?? message.Connections.FirstOrDefault(c => c.Type == "nightbot"); if (_user.TwitchConnection != null) { - _logger.Information("Twitch connection: " + _user.TwitchConnection.Name + " / " + _user.TwitchConnection.AccessToken); + _logger.Debug("Twitch connection: " + _user.TwitchConnection.Name + " / " + _user.TwitchConnection.AccessToken); } var filters = message.WordFilters.Where(f => f.Search != null && f.Replace != null).ToList(); @@ -101,8 +101,9 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers } _logger.Information("TTS is now ready."); - _bus.Send(this, "tts_connected", _user); client.Ready = true; + + _bus.Send(this, "tts_connected", _user); } } } \ No newline at end of file diff --git a/Hermes/Socket/HermesSocketClient.cs b/Hermes/Socket/HermesSocketClient.cs index 3b27e8f..edecbed 100644 --- a/Hermes/Socket/HermesSocketClient.cs +++ b/Hermes/Socket/HermesSocketClient.cs @@ -82,35 +82,36 @@ namespace TwitchChatTTS.Hermes.Socket public override async Task Connect() { - _rwls.EnterWriteLock(); + _rwls.EnterReadLock(); try { if (Connected) return; - - _logger.Debug($"Attempting to connect to {URL}"); - await ConnectAsync(URL); } finally { - _rwls.ExitWriteLock(); + _rwls.ExitReadLock(); } + + _logger.Debug($"Attempting to connect to {URL}"); + await ConnectAsync(URL); + } private async Task Disconnect() { - _rwls.EnterWriteLock(); + _rwls.EnterReadLock(); try { if (!Connected) return; - - await DisconnectAsync(new SocketDisconnectionEventArgs("Normal disconnection", "Disconnection was executed")); } finally { - _rwls.ExitWriteLock(); + _rwls.ExitReadLock(); } + + await DisconnectAsync(new SocketDisconnectionEventArgs("Normal disconnection", "Disconnection was executed")); } public async Task CreateTTSVoice(string voiceName) @@ -437,13 +438,13 @@ namespace TwitchChatTTS.Hermes.Socket _logger.Warning("Tom to Speech websocket client is not connected. Not sending a message."); return; } - - await base.Send(opcode, message); } finally { _rwls.ExitReadLock(); } + + await base.Send(opcode, message); } } } \ No newline at end of file diff --git a/Hermes/Socket/Requests/DeleteGroupAck.cs b/Hermes/Socket/Requests/DeleteGroupAck.cs index 88111b0..9ac8904 100644 --- a/Hermes/Socket/Requests/DeleteGroupAck.cs +++ b/Hermes/Socket/Requests/DeleteGroupAck.cs @@ -1,4 +1,3 @@ -using System.Text.Json; using Serilog; using TwitchChatTTS.Chat.Groups; @@ -8,13 +7,11 @@ namespace TwitchChatTTS.Hermes.Socket.Requests { public string Name => "delete_group"; private readonly IChatterGroupManager _groups; - private readonly JsonSerializerOptions _options; private readonly ILogger _logger; - public DeleteGroupAck(IChatterGroupManager groups, JsonSerializerOptions options, ILogger logger) + public DeleteGroupAck(IChatterGroupManager groups, ILogger logger) { _groups = groups; - _options = options; _logger = logger; } diff --git a/Seven/SevenApiClient.cs b/Seven/SevenApiClient.cs index 9b7c680..3aab29c 100644 --- a/Seven/SevenApiClient.cs +++ b/Seven/SevenApiClient.cs @@ -35,7 +35,13 @@ public class SevenApiClient { _logger.Debug($"Fetching 7tv information using Twitch Id [twitch id: {twitchId}]"); var details = await _web.GetJson($"{API_URL}/users/twitch/" + twitchId); - return details?.EmoteSet; + _logger.Information($"Fetched 7tv emotes [count: {details?.EmoteSet.EmoteCount ?? -1}]"); + if (details?.EmoteSet == null) + { + _logger.Warning("Could not find 7tv emotes linked to your Twitch account."); + return null; + } + return details.EmoteSet; } catch (JsonException e) { diff --git a/TTS.cs b/TTS.cs index 8996ba0..0a20307 100644 --- a/TTS.cs +++ b/TTS.cs @@ -22,8 +22,8 @@ namespace TwitchChatTTS public class TTS : IHostedService { public const int MAJOR_VERSION = 4; - public const int MINOR_VERSION = 8; - public const int PATCH_VERSION = 2; + public const int MINOR_VERSION = 9; + public const int PATCH_VERSION = 3; private readonly User _user; private readonly HermesApiClient _hermesApiClient; @@ -84,7 +84,7 @@ namespace TwitchChatTTS if (string.IsNullOrWhiteSpace(_configuration.Hermes?.Token)) { - _logger.Error("Tom to Speech API token not set in the yml file."); + _logger.Error("Tom to Speech API token not set in the configuration file."); return; } @@ -96,7 +96,7 @@ namespace TwitchChatTTS _logger.Error("Failed to fetch latest TTS version. Something went wrong."); return; } - if (hermesVersion.MajorVersion > TTS.MAJOR_VERSION || hermesVersion.MajorVersion == TTS.MAJOR_VERSION && (hermesVersion.MinorVersion > TTS.MINOR_VERSION || hermesVersion.MinorVersion == TTS.MINOR_VERSION && (hermesVersion.PatchVersion == null || hermesVersion.PatchVersion > TTS.PATCH_VERSION))) + if (hermesVersion.MajorVersion > MAJOR_VERSION || hermesVersion.MajorVersion == MAJOR_VERSION && (hermesVersion.MinorVersion > MINOR_VERSION || hermesVersion.MinorVersion == MINOR_VERSION && (hermesVersion.PatchVersion == null || hermesVersion.PatchVersion > PATCH_VERSION))) { _logger.Information($"A new update for TTS is avaiable! Version {hermesVersion.MajorVersion}.{hermesVersion.MinorVersion}.{hermesVersion.PatchVersion} is available at {hermesVersion.Download}"); var changes = hermesVersion.Changelog.Split("\n"); @@ -111,9 +111,9 @@ namespace TwitchChatTTS } var disposables = new List(); + var connected = _bus.GetTopic("tts_connected"); // 7tv - var connected = _bus.GetTopic("tts_connected"); disposables.Add(connected.FirstAsync().Subscribe(async (data) => { if (data.Value is not User user) diff --git a/TTSListening.cs b/TTSListening.cs index 60aef92..40d9b0c 100644 --- a/TTSListening.cs +++ b/TTSListening.cs @@ -11,19 +11,23 @@ namespace TwitchChatTTS { public class TTSListening : IHostedService { + private const string TTS_API_URL = "https://api.streamelements.com/kappa/v2/speech"; + private readonly AudioPlaybackEngine _playback; private readonly TTSPlayer _player; private readonly TTSConsumer _consumer; private readonly IDisposable _subscription; + private readonly User _user; private readonly ILogger _logger; - public TTSListening(AudioPlaybackEngine playback, TTSPlayer player, TTSPublisher publisher, TTSConsumer consumer, ILogger logger) + public TTSListening(AudioPlaybackEngine playback, TTSPlayer player, TTSPublisher publisher, TTSConsumer consumer, User user, ILogger logger) { _playback = playback; _player = player; _consumer = consumer; _subscription = publisher.Subscribe(consumer); + _user = user; _logger = logger; } @@ -115,7 +119,7 @@ namespace TwitchChatTTS try { - string url = $"https://api.streamelements.com/kappa/v2/speech?voice={message.Voice}&text={HttpUtility.UrlEncode(message.Message.Trim())}"; + string url = $"{TTS_API_URL}?key={_user.StreamElementsOverlayKey}&voice={message.Voice}&text={HttpUtility.UrlEncode(message.Message.Trim())}"; var nws = new NetworkWavSound(url); var provider = new CachedWavProvider(nws); var data = _playback.ConvertSound(provider); diff --git a/Twitch/Redemptions/RedemptionManager.cs b/Twitch/Redemptions/RedemptionManager.cs index 575af70..bb375ea 100644 --- a/Twitch/Redemptions/RedemptionManager.cs +++ b/Twitch/Redemptions/RedemptionManager.cs @@ -110,37 +110,29 @@ namespace TwitchChatTTS.Twitch.Redemptions private void Add(string twitchRedemptionId, string redemptionId) { - _rwls.EnterWriteLock(); - try + if (!_redeems.TryGetValue(twitchRedemptionId, out var redeems)) + _redeems.Add(twitchRedemptionId, redeems = new List()); + + var item = _redemptions.TryGetValue(redemptionId, out var r) ? r : null; + if (item == null) + return; + + var redemptions = redeems.Select(r => _redemptions.TryGetValue(r, out var rr) ? rr : null); + bool added = false; + for (int i = 0; i < redeems.Count; i++) { - if (!_redeems.TryGetValue(twitchRedemptionId, out var redeems)) - _redeems.Add(twitchRedemptionId, redeems = new List()); - - var item = _redemptions.TryGetValue(redemptionId, out var r) ? r : null; - if (item == null) - return; - - var redemptions = redeems.Select(r => _redemptions.TryGetValue(r, out var rr) ? rr : null); - bool added = false; - for (int i = 0; i < redeems.Count; i++) + if (redeems[i] != null && _redemptions.TryGetValue(redeems[i], out var rr)) { - if (redeems[i] != null && _redemptions.TryGetValue(redeems[i], out var rr)) + if (item.Order > rr.Order) { - if (item.Order > rr.Order) - { - redeems.Insert(i, redemptionId); - added = true; - break; - } + redeems.Insert(i, redemptionId); + added = true; + break; } } - if (!added) - redeems.Add(redemptionId); - } - finally - { - _rwls.ExitWriteLock(); } + if (!added) + redeems.Add(redemptionId); _logger.Debug($"Added redemption action [redemption id: {redemptionId}][twitch redemption id: {twitchRedemptionId}]"); } diff --git a/Twitch/Socket/Handlers/ChannelChatMessageHandler.cs b/Twitch/Socket/Handlers/ChannelChatMessageHandler.cs index 235150d..0c05711 100644 --- a/Twitch/Socket/Handlers/ChannelChatMessageHandler.cs +++ b/Twitch/Socket/Handlers/ChannelChatMessageHandler.cs @@ -120,8 +120,7 @@ namespace TwitchChatTTS.Twitch.Socket.Handlers private int GetTotalBits(TwitchChatFragment[] fragments) { return fragments.Where(f => f.Type == "cheermote" && f.Cheermote != null) - .Select(f => f.Cheermote!.Bits) - .Sum(); + .Sum(f => f.Cheermote!.Bits); } private string GetPermissionPath(string? customRewardId, int bits) diff --git a/Twitch/Socket/TwitchConnectionManager.cs b/Twitch/Socket/TwitchConnectionManager.cs index 848d82b..073b76a 100644 --- a/Twitch/Socket/TwitchConnectionManager.cs +++ b/Twitch/Socket/TwitchConnectionManager.cs @@ -142,14 +142,14 @@ namespace TwitchChatTTS.Twitch.Socket _logger.Warning($"Twitch client has been identified, but isn't main or backup [client: {client.UID}][main: {_identified.UID}][backup: {_backup?.UID}]"); clientDisconnect = true; } - - if (clientDisconnect) - client.DisconnectAsync(new SocketDisconnectionEventArgs("Closed", "No need for a tertiary client.")).Wait(); } finally { _mutex.ReleaseMutex(); } + + if (clientDisconnect) + await client.DisconnectAsync(new SocketDisconnectionEventArgs("Closed", "No need for a tertiary client.")); } } } \ No newline at end of file diff --git a/Twitch/Socket/TwitchWebsocketClient.cs b/Twitch/Socket/TwitchWebsocketClient.cs index ebb768f..c6657af 100644 --- a/Twitch/Socket/TwitchWebsocketClient.cs +++ b/Twitch/Socket/TwitchWebsocketClient.cs @@ -183,7 +183,7 @@ namespace TwitchChatTTS.Twitch.Socket while (current < total) { var size = Encoding.UTF8.GetBytes(content.Substring(current), array); - await _socket!.SendAsync(array, WebSocketMessageType.Text, current + size >= total, _cts!.Token); + await _socket!.SendAsync(array, WebSocketMessageType.Text, current + size >= total, CancellationToken.None); current += size; } _logger.Debug("Twitch TX #" + type + ": " + content); diff --git a/User.cs b/User.cs index cda1e7e..657113b 100644 --- a/User.cs +++ b/User.cs @@ -15,6 +15,7 @@ namespace TwitchChatTTS public required string TwitchUsername { get; set; } public required string SevenEmoteSetId { get; set; } public long? OwnerId { get; set; } + public required string StreamElementsOverlayKey { get; set; } public Connection? TwitchConnection { get; set; } public Connection? NightbotConnection { get; set; } diff --git a/Veadotube/VeadoSocketClient.cs b/Veadotube/VeadoSocketClient.cs index 89a3279..452f5f0 100644 --- a/Veadotube/VeadoSocketClient.cs +++ b/Veadotube/VeadoSocketClient.cs @@ -178,7 +178,7 @@ namespace TwitchChatTTS.Veadotube while (current < total) { var size = Encoding.UTF8.GetBytes(content.Substring(current), array); - await _socket.SendAsync(array, WebSocketMessageType.Text, current + size >= total, _cts!.Token); + await _socket.SendAsync(array, WebSocketMessageType.Text, current + size >= total, CancellationToken.None); current += size; } _logger.Debug($"Veado TX [message type: {typeof(T).Name}]: " + content);