Compare commits
1 Commits
fb04f4003f
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| aa89578297 |
@@ -229,6 +229,7 @@ namespace TwitchChatTTS.Chat.Commands.Limits
|
|||||||
var temp = usage.Uses.Skip(sizeDiff);
|
var temp = usage.Uses.Skip(sizeDiff);
|
||||||
var tempSize = usage.Uses.Length - sizeDiff;
|
var tempSize = usage.Uses.Length - sizeDiff;
|
||||||
usage.Uses = temp.Union(new DateTime[Math.Max(0, Limit.Count - tempSize)]).ToArray();
|
usage.Uses = temp.Union(new DateTime[Math.Max(0, Limit.Count - tempSize)]).ToArray();
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_rwls.ExitWriteLock();
|
_rwls.ExitWriteLock();
|
||||||
@@ -256,7 +257,7 @@ namespace TwitchChatTTS.Chat.Commands.Limits
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_rwls.ExitWriteLock();
|
_rwls.ExitUpgradeableReadLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using HermesSocketLibrary.Requests.Messages;
|
using HermesSocketLibrary.Requests.Messages;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
@@ -9,22 +7,35 @@ namespace TwitchChatTTS.Chat.Groups
|
|||||||
{
|
{
|
||||||
private readonly IDictionary<string, Group> _groups;
|
private readonly IDictionary<string, Group> _groups;
|
||||||
private readonly IDictionary<long, ICollection<string>> _chatters;
|
private readonly IDictionary<long, ICollection<string>> _chatters;
|
||||||
|
private readonly ReaderWriterLockSlim _rwls;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
|
||||||
public ChatterGroupManager(ILogger logger)
|
public ChatterGroupManager(ILogger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_groups = new ConcurrentDictionary<string, Group>();
|
_groups = new Dictionary<string, Group>();
|
||||||
_chatters = new ConcurrentDictionary<long, ICollection<string>>();
|
_chatters = new Dictionary<long, ICollection<string>>();
|
||||||
|
_rwls = new ReaderWriterLockSlim();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(Group group)
|
public void Add(Group group)
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_groups.Add(group.Id, group);
|
_groups.Add(group.Id, group);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Add(long chatterId, string groupId)
|
public void Add(long chatterId, string groupId)
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (_chatters.TryGetValue(chatterId, out var list))
|
if (_chatters.TryGetValue(chatterId, out var list))
|
||||||
{
|
{
|
||||||
@@ -34,8 +45,16 @@ namespace TwitchChatTTS.Chat.Groups
|
|||||||
else
|
else
|
||||||
_chatters.Add(chatterId, new List<string>() { groupId });
|
_chatters.Add(chatterId, new List<string>() { groupId });
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Add(long chatter, ICollection<string> groupIds)
|
public void Add(long chatter, ICollection<string> groupIds)
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (_chatters.TryGetValue(chatter, out var list))
|
if (_chatters.TryGetValue(chatter, out var list))
|
||||||
{
|
{
|
||||||
@@ -46,21 +65,45 @@ namespace TwitchChatTTS.Chat.Groups
|
|||||||
else
|
else
|
||||||
_chatters.Add(chatter, groupIds);
|
_chatters.Add(chatter, groupIds);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_groups.Clear();
|
_groups.Clear();
|
||||||
_chatters.Clear();
|
_chatters.Clear();
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Group? Get(string groupId)
|
public Group? Get(string groupId)
|
||||||
|
{
|
||||||
|
_rwls.EnterReadLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (_groups.TryGetValue(groupId, out var group))
|
if (_groups.TryGetValue(groupId, out var group))
|
||||||
return group;
|
return group;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetGroupNamesFor(long chatter)
|
public IEnumerable<string> GetGroupNamesFor(long chatter)
|
||||||
|
{
|
||||||
|
_rwls.EnterReadLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (_chatters.TryGetValue(chatter, out var groups))
|
if (_chatters.TryGetValue(chatter, out var groups))
|
||||||
return groups.Select(g => _groups.TryGetValue(g, out var group) ? group.Name : null)
|
return groups.Select(g => _groups.TryGetValue(g, out var group) ? group.Name : null)
|
||||||
@@ -69,29 +112,61 @@ namespace TwitchChatTTS.Chat.Groups
|
|||||||
|
|
||||||
return Array.Empty<string>();
|
return Array.Empty<string>();
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int GetPriorityFor(long chatter)
|
public int GetPriorityFor(long chatter)
|
||||||
|
{
|
||||||
|
_rwls.EnterReadLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (!_chatters.TryGetValue(chatter, out var groups))
|
if (!_chatters.TryGetValue(chatter, out var groups))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return GetPriorityFor(groups);
|
return GetPriorityFor(groups);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int GetPriorityFor(IEnumerable<string> groupIds)
|
public int GetPriorityFor(IEnumerable<string> groupIds)
|
||||||
|
{
|
||||||
|
_rwls.EnterReadLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var values = groupIds.Select(g => _groups.TryGetValue(g, out var group) ? group : null).Where(g => g != null);
|
var values = groupIds.Select(g => _groups.TryGetValue(g, out var group) ? group : null).Where(g => g != null);
|
||||||
if (values.Any())
|
if (values.Any())
|
||||||
return values.Max(g => g!.Priority);
|
return values.Max(g => g!.Priority);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Modify(Group group)
|
public void Modify(Group group)
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_groups[group.Id] = group;
|
_groups[group.Id] = group;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool Remove(string groupId)
|
public bool Remove(string groupId)
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (_groups.Remove(groupId))
|
if (_groups.Remove(groupId))
|
||||||
{
|
{
|
||||||
@@ -101,8 +176,16 @@ namespace TwitchChatTTS.Chat.Groups
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool Remove(long chatterId, string groupId)
|
public bool Remove(long chatterId, string groupId)
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (_chatters.TryGetValue(chatterId, out var groups))
|
if (_chatters.TryGetValue(chatterId, out var groups))
|
||||||
{
|
{
|
||||||
@@ -113,5 +196,10 @@ namespace TwitchChatTTS.Chat.Groups
|
|||||||
_logger.Debug($"Failed to remove chatter from group [chatter id: {chatterId}][group name: {_groups[groupId].Name}][group id: {groupId}]");
|
_logger.Debug($"Failed to remove chatter from group [chatter id: {chatterId}][group name: {_groups[groupId].Name}][group id: {groupId}]");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,25 +5,38 @@ namespace TwitchChatTTS.Chat.Groups.Permissions
|
|||||||
{
|
{
|
||||||
public class GroupPermissionManager : IGroupPermissionManager
|
public class GroupPermissionManager : IGroupPermissionManager
|
||||||
{
|
{
|
||||||
private PermissionNode _root;
|
private readonly PermissionNode _root;
|
||||||
private ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly ReaderWriterLockSlim _rwls;
|
||||||
|
|
||||||
|
|
||||||
public GroupPermissionManager(ILogger logger)
|
public GroupPermissionManager(ILogger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_root = new PermissionNode(string.Empty, null, null);
|
_root = new PermissionNode(string.Empty, null, null);
|
||||||
|
_rwls = new ReaderWriterLockSlim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool? CheckIfAllowed(string path)
|
public bool? CheckIfAllowed(string path)
|
||||||
|
{
|
||||||
|
_rwls.EnterReadLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var res = Get(path)!.Allow;
|
var res = Get(path)!.Allow;
|
||||||
_logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"}");
|
_logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"}");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool? CheckIfDirectAllowed(string path)
|
public bool? CheckIfDirectAllowed(string path)
|
||||||
|
{
|
||||||
|
_rwls.EnterReadLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var node = Get(path, nullIfMissing: true);
|
var node = Get(path, nullIfMissing: true);
|
||||||
if (node == null)
|
if (node == null)
|
||||||
@@ -33,6 +46,11 @@ namespace TwitchChatTTS.Chat.Groups.Permissions
|
|||||||
_logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"} [direct]");
|
_logger.Debug($"Permission Node GET {path} = {res?.ToString() ?? "null"} [direct]");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool? CheckIfAllowed(IEnumerable<string> groups, string path)
|
public bool? CheckIfAllowed(IEnumerable<string> groups, string path)
|
||||||
{
|
{
|
||||||
@@ -63,16 +81,30 @@ namespace TwitchChatTTS.Chat.Groups.Permissions
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_root.Clear();
|
_root.Clear();
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool Remove(string path)
|
public bool Remove(string path)
|
||||||
|
{
|
||||||
|
_rwls.EnterUpgradeableReadLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var node = Get(path);
|
var node = Get(path);
|
||||||
if (node == null || node.Parent == null)
|
if (node == null || node.Parent == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
|
{
|
||||||
var parts = path.Split('.');
|
var parts = path.Split('.');
|
||||||
var last = parts.Last();
|
var last = parts.Last();
|
||||||
if (parts.Length > 1 && parts[parts.Length - 1] == node.Parent.Name || parts.Length == 1 && node.Parent.Name == null)
|
if (parts.Length > 1 && parts[parts.Length - 1] == node.Parent.Name || parts.Length == 1 && node.Parent.Name == null)
|
||||||
@@ -83,13 +115,31 @@ namespace TwitchChatTTS.Chat.Groups.Permissions
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitUpgradeableReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Set(string path, bool? allow)
|
public void Set(string path, bool? allow)
|
||||||
|
{
|
||||||
|
_rwls.EnterWriteLock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var node = Get(path, true);
|
var node = Get(path, true);
|
||||||
node!.Allow = allow;
|
node!.Allow = allow;
|
||||||
_logger.Debug($"Permission Node ADD {path} = {allow?.ToString() ?? "null"}");
|
_logger.Debug($"Permission Node ADD {path} = {allow?.ToString() ?? "null"}");
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_rwls.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private PermissionNode? Get(string path, bool edit = false, bool nullIfMissing = false)
|
private PermissionNode? Get(string path, bool edit = false, bool nullIfMissing = false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,15 +62,15 @@ namespace TwitchChatTTS.Chat.Messaging
|
|||||||
|
|
||||||
var emoteUsage = GetEmoteUsage(fragments);
|
var emoteUsage = GetEmoteUsage(fragments);
|
||||||
var tasks = new List<Task>();
|
var tasks = new List<Task>();
|
||||||
if (_obs.Streaming && !_user.Slave)
|
if ((!_obs.Connected || _obs.Streaming) && !_user.Slave)
|
||||||
{
|
{
|
||||||
if (emoteUsage.NewEmotes.Any())
|
if (emoteUsage.NewEmotes.Any())
|
||||||
tasks.Add(_hermes.SendEmoteDetails(emoteUsage.NewEmotes));
|
tasks.Add(_hermes.SendEmoteDetails(emoteUsage.NewEmotes));
|
||||||
if (emoteUsage.EmotesUsed.Any() && messageId != null && chatterId != null)
|
if (emoteUsage.EmotesUsed.Any() && messageId != null && chatterId != null)
|
||||||
tasks.Add(_hermes.SendEmoteUsage(messageId, chatterId.Value, emoteUsage.EmotesUsed));
|
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);
|
_user.Chatters.Add(chatterId.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
|
|||||||
|
|
||||||
if (message.AnotherClient)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -51,6 +50,7 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
|
|||||||
_user.TwitchUsername = message.UserName;
|
_user.TwitchUsername = message.UserName;
|
||||||
_user.TwitchUserId = long.Parse(message.ProviderAccountId);
|
_user.TwitchUserId = long.Parse(message.ProviderAccountId);
|
||||||
_user.OwnerId = message.OwnerId;
|
_user.OwnerId = message.OwnerId;
|
||||||
|
_user.StreamElementsOverlayKey = message.StreamElementsOverlayKey;
|
||||||
_user.DefaultTTSVoice = message.DefaultTTSVoice;
|
_user.DefaultTTSVoice = message.DefaultTTSVoice;
|
||||||
_user.VoicesAvailable = new ConcurrentDictionary<string, string>(message.TTSVoicesAvailable);
|
_user.VoicesAvailable = new ConcurrentDictionary<string, string>(message.TTSVoicesAvailable);
|
||||||
_user.VoicesEnabled = new HashSet<string>(message.EnabledTTSVoices);
|
_user.VoicesEnabled = new HashSet<string>(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");
|
_user.NightbotConnection = message.Connections.FirstOrDefault(c => c.Default && c.Type == "nightbot") ?? message.Connections.FirstOrDefault(c => c.Type == "nightbot");
|
||||||
if (_user.TwitchConnection != null)
|
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();
|
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.");
|
_logger.Information("TTS is now ready.");
|
||||||
_bus.Send(this, "tts_connected", _user);
|
|
||||||
client.Ready = true;
|
client.Ready = true;
|
||||||
|
|
||||||
|
_bus.Send(this, "tts_connected", _user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,35 +82,36 @@ namespace TwitchChatTTS.Hermes.Socket
|
|||||||
|
|
||||||
public override async Task Connect()
|
public override async Task Connect()
|
||||||
{
|
{
|
||||||
_rwls.EnterWriteLock();
|
_rwls.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (Connected)
|
if (Connected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_logger.Debug($"Attempting to connect to {URL}");
|
|
||||||
await ConnectAsync(URL);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_rwls.ExitWriteLock();
|
_rwls.ExitReadLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.Debug($"Attempting to connect to {URL}");
|
||||||
|
await ConnectAsync(URL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Disconnect()
|
private async Task Disconnect()
|
||||||
{
|
{
|
||||||
_rwls.EnterWriteLock();
|
_rwls.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!Connected)
|
if (!Connected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await DisconnectAsync(new SocketDisconnectionEventArgs("Normal disconnection", "Disconnection was executed"));
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_rwls.ExitWriteLock();
|
_rwls.ExitReadLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await DisconnectAsync(new SocketDisconnectionEventArgs("Normal disconnection", "Disconnection was executed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CreateTTSVoice(string voiceName)
|
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.");
|
_logger.Warning("Tom to Speech websocket client is not connected. Not sending a message.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await base.Send(opcode, message);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_rwls.ExitReadLock();
|
_rwls.ExitReadLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await base.Send(opcode, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using TwitchChatTTS.Chat.Groups;
|
using TwitchChatTTS.Chat.Groups;
|
||||||
|
|
||||||
@@ -8,13 +7,11 @@ namespace TwitchChatTTS.Hermes.Socket.Requests
|
|||||||
{
|
{
|
||||||
public string Name => "delete_group";
|
public string Name => "delete_group";
|
||||||
private readonly IChatterGroupManager _groups;
|
private readonly IChatterGroupManager _groups;
|
||||||
private readonly JsonSerializerOptions _options;
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public DeleteGroupAck(IChatterGroupManager groups, JsonSerializerOptions options, ILogger logger)
|
public DeleteGroupAck(IChatterGroupManager groups, ILogger logger)
|
||||||
{
|
{
|
||||||
_groups = groups;
|
_groups = groups;
|
||||||
_options = options;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,13 @@ public class SevenApiClient
|
|||||||
{
|
{
|
||||||
_logger.Debug($"Fetching 7tv information using Twitch Id [twitch id: {twitchId}]");
|
_logger.Debug($"Fetching 7tv information using Twitch Id [twitch id: {twitchId}]");
|
||||||
var details = await _web.GetJson<UserDetails>($"{API_URL}/users/twitch/" + twitchId);
|
var details = await _web.GetJson<UserDetails>($"{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)
|
catch (JsonException e)
|
||||||
{
|
{
|
||||||
|
|||||||
10
TTS.cs
10
TTS.cs
@@ -22,8 +22,8 @@ namespace TwitchChatTTS
|
|||||||
public class TTS : IHostedService
|
public class TTS : IHostedService
|
||||||
{
|
{
|
||||||
public const int MAJOR_VERSION = 4;
|
public const int MAJOR_VERSION = 4;
|
||||||
public const int MINOR_VERSION = 8;
|
public const int MINOR_VERSION = 9;
|
||||||
public const int PATCH_VERSION = 2;
|
public const int PATCH_VERSION = 3;
|
||||||
|
|
||||||
private readonly User _user;
|
private readonly User _user;
|
||||||
private readonly HermesApiClient _hermesApiClient;
|
private readonly HermesApiClient _hermesApiClient;
|
||||||
@@ -84,7 +84,7 @@ namespace TwitchChatTTS
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(_configuration.Hermes?.Token))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ namespace TwitchChatTTS
|
|||||||
_logger.Error("Failed to fetch latest TTS version. Something went wrong.");
|
_logger.Error("Failed to fetch latest TTS version. Something went wrong.");
|
||||||
return;
|
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}");
|
_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");
|
var changes = hermesVersion.Changelog.Split("\n");
|
||||||
@@ -111,9 +111,9 @@ namespace TwitchChatTTS
|
|||||||
}
|
}
|
||||||
|
|
||||||
var disposables = new List<IDisposable>();
|
var disposables = new List<IDisposable>();
|
||||||
|
var connected = _bus.GetTopic("tts_connected");
|
||||||
|
|
||||||
// 7tv
|
// 7tv
|
||||||
var connected = _bus.GetTopic("tts_connected");
|
|
||||||
disposables.Add(connected.FirstAsync().Subscribe(async (data) =>
|
disposables.Add(connected.FirstAsync().Subscribe(async (data) =>
|
||||||
{
|
{
|
||||||
if (data.Value is not User user)
|
if (data.Value is not User user)
|
||||||
|
|||||||
@@ -11,19 +11,23 @@ namespace TwitchChatTTS
|
|||||||
{
|
{
|
||||||
public class TTSListening : IHostedService
|
public class TTSListening : IHostedService
|
||||||
{
|
{
|
||||||
|
private const string TTS_API_URL = "https://api.streamelements.com/kappa/v2/speech";
|
||||||
|
|
||||||
private readonly AudioPlaybackEngine _playback;
|
private readonly AudioPlaybackEngine _playback;
|
||||||
private readonly TTSPlayer _player;
|
private readonly TTSPlayer _player;
|
||||||
private readonly TTSConsumer _consumer;
|
private readonly TTSConsumer _consumer;
|
||||||
private readonly IDisposable _subscription;
|
private readonly IDisposable _subscription;
|
||||||
|
private readonly User _user;
|
||||||
private readonly ILogger _logger;
|
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;
|
_playback = playback;
|
||||||
_player = player;
|
_player = player;
|
||||||
_consumer = consumer;
|
_consumer = consumer;
|
||||||
_subscription = publisher.Subscribe(consumer);
|
_subscription = publisher.Subscribe(consumer);
|
||||||
|
_user = user;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +119,7 @@ namespace TwitchChatTTS
|
|||||||
|
|
||||||
try
|
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 nws = new NetworkWavSound(url);
|
||||||
var provider = new CachedWavProvider(nws);
|
var provider = new CachedWavProvider(nws);
|
||||||
var data = _playback.ConvertSound(provider);
|
var data = _playback.ConvertSound(provider);
|
||||||
|
|||||||
@@ -109,9 +109,6 @@ namespace TwitchChatTTS.Twitch.Redemptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void Add(string twitchRedemptionId, string redemptionId)
|
private void Add(string twitchRedemptionId, string redemptionId)
|
||||||
{
|
|
||||||
_rwls.EnterWriteLock();
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (!_redeems.TryGetValue(twitchRedemptionId, out var redeems))
|
if (!_redeems.TryGetValue(twitchRedemptionId, out var redeems))
|
||||||
_redeems.Add(twitchRedemptionId, redeems = new List<string>());
|
_redeems.Add(twitchRedemptionId, redeems = new List<string>());
|
||||||
@@ -136,11 +133,6 @@ namespace TwitchChatTTS.Twitch.Redemptions
|
|||||||
}
|
}
|
||||||
if (!added)
|
if (!added)
|
||||||
redeems.Add(redemptionId);
|
redeems.Add(redemptionId);
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_rwls.ExitWriteLock();
|
|
||||||
}
|
|
||||||
_logger.Debug($"Added redemption action [redemption id: {redemptionId}][twitch redemption id: {twitchRedemptionId}]");
|
_logger.Debug($"Added redemption action [redemption id: {redemptionId}][twitch redemption id: {twitchRedemptionId}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,8 +120,7 @@ namespace TwitchChatTTS.Twitch.Socket.Handlers
|
|||||||
private int GetTotalBits(TwitchChatFragment[] fragments)
|
private int GetTotalBits(TwitchChatFragment[] fragments)
|
||||||
{
|
{
|
||||||
return fragments.Where(f => f.Type == "cheermote" && f.Cheermote != null)
|
return fragments.Where(f => f.Type == "cheermote" && f.Cheermote != null)
|
||||||
.Select(f => f.Cheermote!.Bits)
|
.Sum(f => f.Cheermote!.Bits);
|
||||||
.Sum();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetPermissionPath(string? customRewardId, int bits)
|
private string GetPermissionPath(string? customRewardId, int bits)
|
||||||
|
|||||||
@@ -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}]");
|
_logger.Warning($"Twitch client has been identified, but isn't main or backup [client: {client.UID}][main: {_identified.UID}][backup: {_backup?.UID}]");
|
||||||
clientDisconnect = true;
|
clientDisconnect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientDisconnect)
|
|
||||||
client.DisconnectAsync(new SocketDisconnectionEventArgs("Closed", "No need for a tertiary client.")).Wait();
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_mutex.ReleaseMutex();
|
_mutex.ReleaseMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clientDisconnect)
|
||||||
|
await client.DisconnectAsync(new SocketDisconnectionEventArgs("Closed", "No need for a tertiary client."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,7 @@ namespace TwitchChatTTS.Twitch.Socket
|
|||||||
while (current < total)
|
while (current < total)
|
||||||
{
|
{
|
||||||
var size = Encoding.UTF8.GetBytes(content.Substring(current), array);
|
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;
|
current += size;
|
||||||
}
|
}
|
||||||
_logger.Debug("Twitch TX #" + type + ": " + content);
|
_logger.Debug("Twitch TX #" + type + ": " + content);
|
||||||
|
|||||||
1
User.cs
1
User.cs
@@ -15,6 +15,7 @@ namespace TwitchChatTTS
|
|||||||
public required string TwitchUsername { get; set; }
|
public required string TwitchUsername { get; set; }
|
||||||
public required string SevenEmoteSetId { get; set; }
|
public required string SevenEmoteSetId { get; set; }
|
||||||
public long? OwnerId { get; set; }
|
public long? OwnerId { get; set; }
|
||||||
|
public required string StreamElementsOverlayKey { get; set; }
|
||||||
|
|
||||||
public Connection? TwitchConnection { get; set; }
|
public Connection? TwitchConnection { get; set; }
|
||||||
public Connection? NightbotConnection { get; set; }
|
public Connection? NightbotConnection { get; set; }
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ namespace TwitchChatTTS.Veadotube
|
|||||||
while (current < total)
|
while (current < total)
|
||||||
{
|
{
|
||||||
var size = Encoding.UTF8.GetBytes(content.Substring(current), array);
|
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;
|
current += size;
|
||||||
}
|
}
|
||||||
_logger.Debug($"Veado TX [message type: {typeof(T).Name}]: " + content);
|
_logger.Debug($"Veado TX [message type: {typeof(T).Name}]: " + content);
|
||||||
|
|||||||
Reference in New Issue
Block a user