Twitch connection now relies on events to connect. Added logging for when TTS filter is not a regex. Minor code clean up.
This commit is contained in:
@ -53,19 +53,24 @@ namespace TwitchChatTTS.Hermes.Socket.Handlers
|
|||||||
_user.VoicesEnabled = new HashSet<string>(message.EnabledTTSVoices);
|
_user.VoicesEnabled = new HashSet<string>(message.EnabledTTSVoices);
|
||||||
_user.TwitchConnection = message.Connections.FirstOrDefault(c => c.Default && c.Type == "twitch");
|
_user.TwitchConnection = message.Connections.FirstOrDefault(c => c.Default && c.Type == "twitch");
|
||||||
_user.NightbotConnection = message.Connections.FirstOrDefault(c => c.Default && c.Type == "nightbot");
|
_user.NightbotConnection = message.Connections.FirstOrDefault(c => c.Default && c.Type == "nightbot");
|
||||||
|
if (_user.TwitchConnection != null)
|
||||||
_bus.Send(this, "twitch id", _user.TwitchUserId);
|
{
|
||||||
|
_logger.Information("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();
|
||||||
foreach (var filter in filters)
|
foreach (var filter in filters)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var re = new Regex(filter.Search, ((RegexOptions) filter.Flag) | RegexOptions.Compiled);
|
var re = new Regex(filter.Search, ((RegexOptions)filter.Flag) | RegexOptions.Compiled);
|
||||||
re.Match(string.Empty);
|
re.Match(string.Empty);
|
||||||
filter.Regex = re;
|
filter.Regex = re;
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception)
|
||||||
|
{
|
||||||
|
_logger.Warning($"Failed to create a regular expression for a TTS filter [filter id: {filter.Search}]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_user.RegexFilters = filters;
|
_user.RegexFilters = filters;
|
||||||
|
|
||||||
@ -93,6 +98,7 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ namespace TwitchChatTTS.Hermes.Socket
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_logger.Information("Initializing Hermes websocket client.");
|
_logger.Information("Initializing Tom to Speech websocket client.");
|
||||||
|
|
||||||
OnConnected += async (sender, e) =>
|
OnConnected += async (sender, e) =>
|
||||||
{
|
{
|
||||||
@ -257,7 +257,7 @@ namespace TwitchChatTTS.Hermes.Socket
|
|||||||
return;
|
return;
|
||||||
Connected = true;
|
Connected = true;
|
||||||
}
|
}
|
||||||
_logger.Information("Hermes websocket client connected.");
|
_logger.Information("Tom to Speech websocket client connected.");
|
||||||
|
|
||||||
_heartbeatTimer.Enabled = true;
|
_heartbeatTimer.Enabled = true;
|
||||||
LastHeartbeatReceived = DateTime.UtcNow;
|
LastHeartbeatReceived = DateTime.UtcNow;
|
||||||
@ -281,7 +281,7 @@ namespace TwitchChatTTS.Hermes.Socket
|
|||||||
|
|
||||||
LoggedIn = false;
|
LoggedIn = false;
|
||||||
Ready = false;
|
Ready = false;
|
||||||
_logger.Warning("Hermes websocket client disconnected.");
|
_logger.Warning("Tom to Speech websocket client disconnected.");
|
||||||
|
|
||||||
_heartbeatTimer.Enabled = false;
|
_heartbeatTimer.Enabled = false;
|
||||||
await Reconnect(_backoff);
|
await Reconnect(_backoff);
|
||||||
@ -396,7 +396,7 @@ namespace TwitchChatTTS.Hermes.Socket
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to send a heartbeat back to the Hermes websocket server.");
|
_logger.Error(ex, "Failed to send a heartbeat back to the Tom to Speech websocket server.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (signalTime - LastHeartbeatReceived > TimeSpan.FromSeconds(120))
|
else if (signalTime - LastHeartbeatReceived > TimeSpan.FromSeconds(120))
|
||||||
@ -407,7 +407,7 @@ namespace TwitchChatTTS.Hermes.Socket
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Failed to disconnect from Hermes websocket server.");
|
_logger.Error(ex, "Failed to disconnect from Tom to Speech websocket server.");
|
||||||
Ready = false;
|
Ready = false;
|
||||||
LoggedIn = false;
|
LoggedIn = false;
|
||||||
Connected = false;
|
Connected = false;
|
||||||
@ -423,7 +423,7 @@ namespace TwitchChatTTS.Hermes.Socket
|
|||||||
{
|
{
|
||||||
if (!Connected)
|
if (!Connected)
|
||||||
{
|
{
|
||||||
_logger.Warning("Hermes 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ namespace TwitchChatTTS.Hermes.Socket.Requests
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
_logger.Warning($"Failed to generate a Regular Expression using '{filter.Search}' [filter id: {filter.Id}]");
|
_logger.Warning($"Failed to create a regular expression for a TTS filter [filter id: {filter.Search}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug($"Filter data [filter id: {filter.Id}][search: {filter.Search}][replace: {filter.Replace}]");
|
_logger.Debug($"Filter data [filter id: {filter.Id}][search: {filter.Search}][replace: {filter.Replace}]");
|
||||||
|
@ -33,11 +33,14 @@ namespace TwitchChatTTS.Hermes.Socket.Requests
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var re = new Regex(filter.Search, ((RegexOptions) filter.Flag) | RegexOptions.Compiled);
|
var re = new Regex(filter.Search, ((RegexOptions)filter.Flag) | RegexOptions.Compiled);
|
||||||
re.Match(string.Empty);
|
re.Match(string.Empty);
|
||||||
filter.Regex = re;
|
filter.Regex = re;
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception)
|
||||||
|
{
|
||||||
|
_logger.Warning($"Failed to create a regular expression for a TTS filter [filter id: {filter.Search}]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_user.RegexFilters = filters;
|
_user.RegexFilters = filters;
|
||||||
_logger.Information($"TTS word filters [count: {_user.RegexFilters.Count}] have been refreshed.");
|
_logger.Information($"TTS word filters [count: {_user.RegexFilters.Count}] have been refreshed.");
|
||||||
|
@ -52,7 +52,10 @@ namespace TwitchChatTTS.Hermes.Socket.Requests
|
|||||||
re.Match(string.Empty);
|
re.Match(string.Empty);
|
||||||
current.Regex = re;
|
current.Regex = re;
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception)
|
||||||
|
{
|
||||||
|
_logger.Warning($"Failed to create a regular expression for a TTS filter [filter id: {filter.Search}]");
|
||||||
|
}
|
||||||
|
|
||||||
_logger.Information($"Filter has been updated [filter id: {filter.Id}]");
|
_logger.Information($"Filter has been updated [filter id: {filter.Id}]");
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,6 @@ s.AddKeyedTransient<SocketClient<TwitchWebsocketMessage>, TwitchWebsocketClient>
|
|||||||
{
|
{
|
||||||
var factory = sp.GetRequiredService<ITwitchConnectionManager>();
|
var factory = sp.GetRequiredService<ITwitchConnectionManager>();
|
||||||
var client = factory.GetWorkingClient();
|
var client = factory.GetWorkingClient();
|
||||||
client.Connect().Wait();
|
|
||||||
return client;
|
return client;
|
||||||
});
|
});
|
||||||
s.AddKeyedTransient<SocketClient<TwitchWebsocketMessage>, TwitchWebsocketClient>("twitch-create");
|
s.AddKeyedTransient<SocketClient<TwitchWebsocketMessage>, TwitchWebsocketClient>("twitch-create");
|
||||||
|
104
TTS.cs
104
TTS.cs
@ -1,7 +1,6 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using NAudio.Wave.SampleProviders;
|
|
||||||
using org.mariuszgromada.math.mxparser;
|
using org.mariuszgromada.math.mxparser;
|
||||||
using TwitchChatTTS.Hermes.Socket;
|
using TwitchChatTTS.Hermes.Socket;
|
||||||
using TwitchChatTTS.Seven.Socket;
|
using TwitchChatTTS.Seven.Socket;
|
||||||
@ -13,10 +12,10 @@ using TwitchChatTTS.Twitch.Socket.Messages;
|
|||||||
using TwitchChatTTS.Twitch.Socket;
|
using TwitchChatTTS.Twitch.Socket;
|
||||||
using TwitchChatTTS.Chat.Commands;
|
using TwitchChatTTS.Chat.Commands;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using TwitchChatTTS.Chat.Speech;
|
|
||||||
using TwitchChatTTS.Veadotube;
|
using TwitchChatTTS.Veadotube;
|
||||||
using TwitchChatTTS.Bus;
|
using TwitchChatTTS.Bus;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
|
using System.Net.WebSockets;
|
||||||
|
|
||||||
namespace TwitchChatTTS
|
namespace TwitchChatTTS
|
||||||
{
|
{
|
||||||
@ -36,8 +35,6 @@ namespace TwitchChatTTS
|
|||||||
private readonly ICommandFactory _commandFactory;
|
private readonly ICommandFactory _commandFactory;
|
||||||
private readonly ICommandManager _commandManager;
|
private readonly ICommandManager _commandManager;
|
||||||
private readonly IEmoteDatabase _emotes;
|
private readonly IEmoteDatabase _emotes;
|
||||||
private readonly TTSPlayer _player;
|
|
||||||
private readonly AudioPlaybackEngine _playback;
|
|
||||||
private readonly ServiceBusCentral _bus;
|
private readonly ServiceBusCentral _bus;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
@ -54,8 +51,6 @@ namespace TwitchChatTTS
|
|||||||
ICommandFactory commandFactory,
|
ICommandFactory commandFactory,
|
||||||
ICommandManager commandManager,
|
ICommandManager commandManager,
|
||||||
IEmoteDatabase emotes,
|
IEmoteDatabase emotes,
|
||||||
TTSPlayer player,
|
|
||||||
AudioPlaybackEngine playback,
|
|
||||||
ServiceBusCentral bus,
|
ServiceBusCentral bus,
|
||||||
Configuration configuration,
|
Configuration configuration,
|
||||||
ILogger logger
|
ILogger logger
|
||||||
@ -72,8 +67,6 @@ namespace TwitchChatTTS
|
|||||||
_commandFactory = commandFactory;
|
_commandFactory = commandFactory;
|
||||||
_commandManager = commandManager;
|
_commandManager = commandManager;
|
||||||
_emotes = emotes;
|
_emotes = emotes;
|
||||||
_player = player;
|
|
||||||
_playback = playback;
|
|
||||||
_bus = bus;
|
_bus = bus;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@ -87,7 +80,7 @@ namespace TwitchChatTTS
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(_configuration.Hermes?.Token))
|
if (string.IsNullOrWhiteSpace(_configuration.Hermes?.Token))
|
||||||
{
|
{
|
||||||
_logger.Error("Hermes API token not set in the configuration file.");
|
_logger.Error("Tom to Speech API token not set in the yml file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,56 +106,70 @@ namespace TwitchChatTTS
|
|||||||
_logger.Warning("Failed to check for version updates.");
|
_logger.Warning("Failed to check for version updates.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var disposables = new List<IDisposable>();
|
||||||
|
|
||||||
// 7tv
|
// 7tv
|
||||||
var twitchTopic = _bus.GetTopic("twitch id");
|
var connected = _bus.GetTopic("tts_connected");
|
||||||
twitchTopic.FirstAsync().Subscribe(async (data) =>
|
disposables.Add(connected.FirstAsync().Subscribe(async (data) =>
|
||||||
{
|
{
|
||||||
var twitchId = data.Value?.ToString();
|
if (data.Value is not User user)
|
||||||
if (twitchId == null)
|
{
|
||||||
|
_logger.Warning("Something went wrong. Unable to fetch 7tv data.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if (user.TwitchUserId == default)
|
||||||
|
{
|
||||||
|
_logger.Warning("Unable to fetch 7tv data. If this is wrong, ensure your Tom to Speech token is valid.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var emoteSet = await _sevenApiClient.FetchChannelEmoteSet(_user.TwitchUserId);
|
var emoteSet = await _sevenApiClient.FetchChannelEmoteSet(_user.TwitchUserId);
|
||||||
if (emoteSet != null)
|
if (emoteSet != null)
|
||||||
|
{
|
||||||
_user.SevenEmoteSetId = emoteSet.Id;
|
_user.SevenEmoteSetId = emoteSet.Id;
|
||||||
|
_logger.Debug($"Fetched the 7tv emote set id [emote set id: {emoteSet.Id}]");
|
||||||
|
}
|
||||||
|
|
||||||
await InitializeEmotes(_sevenApiClient, emoteSet);
|
await InitializeEmotes(_sevenApiClient, emoteSet);
|
||||||
await InitializeSevenTv();
|
await InitializeSevenTv();
|
||||||
});
|
}));
|
||||||
|
|
||||||
await InitializeHermesWebsocket();
|
disposables.Add(connected.FirstAsync().Subscribe(async (data) =>
|
||||||
|
|
||||||
_playback.AddOnMixerInputEnded((object? s, SampleProviderEventArgs e) =>
|
|
||||||
{
|
{
|
||||||
if (_player.Playing?.Audio == e.SampleProvider)
|
if (data.Value is not User user)
|
||||||
{
|
{
|
||||||
_player.Playing = null;
|
_logger.Warning("Something went wrong. Not connecting to Twitch.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (user.TwitchUserId == default)
|
||||||
|
{
|
||||||
|
_logger.Warning("Not connecting to Twitch. If this is wrong, ensure your Tom to Speech token is valid.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_veado.Initialize();
|
await _twitch.Connect();
|
||||||
await _veado.Connect();
|
}
|
||||||
}
|
catch (Exception e)
|
||||||
catch (Exception e)
|
{
|
||||||
{
|
_logger.Error(e, "Failed to connect to Twitch websocket server.");
|
||||||
_logger.Warning(e, "Failed to connect to Veado websocket server.");
|
}
|
||||||
}
|
}));
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await _twitch.Connect();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Error(e, "Failed to connect to Twitch websocket server.");
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(30));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_commandManager.Update(_commandFactory);
|
_commandManager.Update(_commandFactory);
|
||||||
|
|
||||||
|
await InitializeVeadotube();
|
||||||
|
await InitializeHermesWebsocket();
|
||||||
await InitializeObs();
|
await InitializeObs();
|
||||||
|
|
||||||
|
// Check if user has successfully connected.
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||||
|
if (_user.TwitchUserId == default)
|
||||||
|
_logger.Warning("Ensure your Tom to Speech token in the tts.config.yml file is valid.");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StopAsync(CancellationToken cancellationToken)
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
@ -181,6 +188,10 @@ namespace TwitchChatTTS
|
|||||||
_hermes.Initialize();
|
_hermes.Initialize();
|
||||||
await _hermes.Connect();
|
await _hermes.Connect();
|
||||||
}
|
}
|
||||||
|
catch (WebSocketException e) when (e.Message.Contains("The server returned status code '502'"))
|
||||||
|
{
|
||||||
|
_logger.Error("Could not connect to Tom to Speech server.");
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Error(e, "Connecting to hermes failed. Skipping hermes websockets.");
|
_logger.Error(e, "Connecting to hermes failed. Skipping hermes websockets.");
|
||||||
@ -213,6 +224,19 @@ namespace TwitchChatTTS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task InitializeVeadotube()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_veado.Initialize();
|
||||||
|
await _veado.Connect();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Warning(e, "Failed to connect to Veado websocket server.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task InitializeEmotes(SevenApiClient sevenapi, EmoteSet? channelEmotes)
|
private async Task InitializeEmotes(SevenApiClient sevenapi, EmoteSet? channelEmotes)
|
||||||
{
|
{
|
||||||
var globalEmotes = await sevenapi.FetchGlobalSevenEmotes();
|
var globalEmotes = await sevenapi.FetchGlobalSevenEmotes();
|
||||||
|
@ -30,6 +30,14 @@ namespace TwitchChatTTS
|
|||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
_playback.AddOnMixerInputEnded((object? s, SampleProviderEventArgs e) =>
|
||||||
|
{
|
||||||
|
if (_player.Playing?.Audio == e.SampleProvider)
|
||||||
|
{
|
||||||
|
_player.Playing = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -29,18 +29,9 @@ namespace TwitchChatTTS.Twitch.Socket.Handlers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int waited = 0;
|
var twitchConnection = _user.TwitchConnection!;
|
||||||
while ((_user.TwitchUserId <= 0 || _user.TwitchConnection == null) && ++waited < 5)
|
_api.Initialize(twitchConnection.ClientId, twitchConnection.AccessToken);
|
||||||
await Task.Delay(TimeSpan.FromSeconds(1));
|
var span = twitchConnection.ExpiresAt - DateTime.Now;
|
||||||
|
|
||||||
if (_user.TwitchConnection == null)
|
|
||||||
{
|
|
||||||
_logger.Error("Ensure you have linked either your Twitch account or TTS' bot to your TTS account. Twitch client will not be connecting.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_api.Initialize(_user.TwitchConnection.ClientId, _user.TwitchConnection.AccessToken);
|
|
||||||
var span = _user.TwitchConnection.ExpiresAt - DateTime.Now;
|
|
||||||
var timeLeft = span.Days >= 2 ? span.Days + " days" : (span.Hours >= 2 ? span.Hours + " hours" : span.Minutes + " minutes");
|
var timeLeft = span.Days >= 2 ? span.Days + " days" : (span.Hours >= 2 ? span.Hours + " hours" : span.Minutes + " minutes");
|
||||||
if (span.Days >= 3)
|
if (span.Days >= 3)
|
||||||
_logger.Information($"Twitch connection has {timeLeft} before it is revoked.");
|
_logger.Information($"Twitch connection has {timeLeft} before it is revoked.");
|
||||||
@ -48,7 +39,7 @@ namespace TwitchChatTTS.Twitch.Socket.Handlers
|
|||||||
_logger.Warning($"Twitch connection has {timeLeft} before it is revoked. Refreshing the token is soon required.");
|
_logger.Warning($"Twitch connection has {timeLeft} before it is revoked. Refreshing the token is soon required.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Error("Twitch connection has its permissions revoked. Refresh the token. Twith client will not be connecting.");
|
_logger.Error("Twitch connection has its permissions revoked. Refresh the token. Twitch client will not be connecting.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user