2024-03-15 08:27:35 -04:00
|
|
|
using System.Collections.Concurrent;
|
|
|
|
using System.Text.Json;
|
|
|
|
using CommonSocketLibrary.Abstract;
|
|
|
|
using CommonSocketLibrary.Common;
|
|
|
|
using HermesSocketLibrary.Requests.Messages;
|
|
|
|
using HermesSocketLibrary.Socket.Data;
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2024-06-16 20:19:31 -04:00
|
|
|
using Serilog;
|
|
|
|
using TwitchChatTTS.Seven;
|
2024-03-15 08:27:35 -04:00
|
|
|
|
|
|
|
namespace TwitchChatTTS.Hermes.Socket.Handlers
|
|
|
|
{
|
|
|
|
public class RequestAckHandler : IWebSocketHandler
|
|
|
|
{
|
|
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
|
private readonly JsonSerializerOptions _options;
|
|
|
|
private readonly ILogger _logger;
|
2024-06-16 20:19:31 -04:00
|
|
|
|
|
|
|
private readonly object _voicesAvailableLock = new object();
|
|
|
|
|
2024-03-15 08:27:35 -04:00
|
|
|
public int OperationCode { get; set; } = 4;
|
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
public RequestAckHandler(IServiceProvider serviceProvider, JsonSerializerOptions options, ILogger logger)
|
|
|
|
{
|
2024-03-15 08:27:35 -04:00
|
|
|
_serviceProvider = serviceProvider;
|
|
|
|
_options = options;
|
|
|
|
_logger = logger;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task Execute<Data>(SocketClient<WebSocketMessage> sender, Data message)
|
|
|
|
{
|
|
|
|
if (message is not RequestAckMessage obj || obj == null)
|
|
|
|
return;
|
|
|
|
if (obj.Request == null)
|
|
|
|
return;
|
|
|
|
var context = _serviceProvider.GetRequiredService<User>();
|
|
|
|
if (context == null)
|
|
|
|
return;
|
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
if (obj.Request.Type == "get_tts_voices")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Updating all available voices for TTS.");
|
2024-03-15 08:27:35 -04:00
|
|
|
var voices = JsonSerializer.Deserialize<IEnumerable<VoiceDetails>>(obj.Data.ToString(), _options);
|
|
|
|
if (voices == null)
|
|
|
|
return;
|
2024-06-16 20:19:31 -04:00
|
|
|
|
|
|
|
lock (_voicesAvailableLock)
|
|
|
|
{
|
|
|
|
context.VoicesAvailable = voices.ToDictionary(e => e.Id, e => e.Name);
|
|
|
|
}
|
|
|
|
_logger.Information("Updated all available voices for TTS.");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "create_tts_user")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Adding new tts voice for user.");
|
|
|
|
if (!long.TryParse(obj.Request.Data["user"].ToString(), out long chatterId))
|
2024-03-15 08:27:35 -04:00
|
|
|
return;
|
2024-06-16 20:19:31 -04:00
|
|
|
string userId = obj.Request.Data["user"].ToString();
|
|
|
|
string voice = obj.Request.Data["voice"].ToString();
|
|
|
|
|
|
|
|
context.VoicesSelected.Add(chatterId, voice);
|
|
|
|
_logger.Information($"Added new TTS voice [voice: {voice}] for user [user id: {userId}]");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "update_tts_user")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Updating user's voice");
|
|
|
|
if (!long.TryParse(obj.Request.Data["chatter"].ToString(), out long chatterId))
|
2024-03-15 08:27:35 -04:00
|
|
|
return;
|
2024-06-16 20:19:31 -04:00
|
|
|
string userId = obj.Request.Data["user"].ToString();
|
|
|
|
string voice = obj.Request.Data["voice"].ToString();
|
|
|
|
|
|
|
|
context.VoicesSelected[chatterId] = voice;
|
|
|
|
_logger.Information($"Updated TTS voice [voice: {voice}] for user [user id: {userId}]");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "create_tts_voice")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Creating new tts voice.");
|
|
|
|
string? voice = obj.Request.Data["voice"].ToString();
|
2024-03-15 08:27:35 -04:00
|
|
|
string? voiceId = obj.Data.ToString();
|
|
|
|
if (voice == null || voiceId == null)
|
|
|
|
return;
|
|
|
|
|
2024-06-16 20:19:31 -04:00
|
|
|
lock (_voicesAvailableLock)
|
|
|
|
{
|
|
|
|
var list = context.VoicesAvailable.ToDictionary(k => k.Key, v => v.Value);
|
|
|
|
list.Add(voiceId, voice);
|
|
|
|
context.VoicesAvailable = list;
|
2024-03-15 08:27:35 -04:00
|
|
|
}
|
2024-06-16 20:19:31 -04:00
|
|
|
_logger.Information($"Created new tts voice [voice: {voice}][id: {voiceId}].");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "delete_tts_voice")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Deleting tts voice.");
|
|
|
|
var voice = obj.Request.Data["voice"].ToString();
|
|
|
|
if (!context.VoicesAvailable.TryGetValue(voice, out string voiceName) || voiceName == null)
|
2024-03-15 08:27:35 -04:00
|
|
|
return;
|
2024-06-16 20:19:31 -04:00
|
|
|
|
|
|
|
lock (_voicesAvailableLock)
|
|
|
|
{
|
|
|
|
var dict = context.VoicesAvailable.ToDictionary(k => k.Key, v => v.Value);
|
|
|
|
dict.Remove(voice);
|
|
|
|
context.VoicesAvailable.Remove(voice);
|
2024-03-15 08:27:35 -04:00
|
|
|
}
|
2024-06-16 20:19:31 -04:00
|
|
|
_logger.Information($"Deleted a voice [voice: {voiceName}]");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "update_tts_voice")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Updating TTS voice.");
|
|
|
|
string voiceId = obj.Request.Data["idd"].ToString();
|
|
|
|
string voice = obj.Request.Data["voice"].ToString();
|
|
|
|
|
|
|
|
if (!context.VoicesAvailable.TryGetValue(voiceId, out string voiceName) || voiceName == null)
|
|
|
|
return;
|
|
|
|
|
2024-03-15 08:27:35 -04:00
|
|
|
context.VoicesAvailable[voiceId] = voice;
|
2024-06-16 20:19:31 -04:00
|
|
|
_logger.Information($"Updated TTS voice [voice: {voice}][id: {voiceId}]");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "get_tts_users")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Updating all chatters' selected voice.");
|
2024-03-15 08:27:35 -04:00
|
|
|
var users = JsonSerializer.Deserialize<IDictionary<long, string>>(obj.Data.ToString(), _options);
|
|
|
|
if (users == null)
|
|
|
|
return;
|
2024-06-16 20:19:31 -04:00
|
|
|
|
2024-03-15 08:27:35 -04:00
|
|
|
var temp = new ConcurrentDictionary<long, string>();
|
|
|
|
foreach (var entry in users)
|
|
|
|
temp.TryAdd(entry.Key, entry.Value);
|
|
|
|
context.VoicesSelected = temp;
|
2024-06-16 20:19:31 -04:00
|
|
|
_logger.Information($"Updated {temp.Count()} chatters' selected voice.");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "get_chatter_ids")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Fetching all chatters' id.");
|
|
|
|
var chatters = JsonSerializer.Deserialize<IEnumerable<long>>(obj.Data.ToString(), _options);
|
|
|
|
if (chatters == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
var client = _serviceProvider.GetRequiredService<ChatMessageHandler>();
|
|
|
|
client.Chatters = [.. chatters];
|
|
|
|
_logger.Information($"Fetched {chatters.Count()} chatters' id.");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "get_emotes")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Updating emotes.");
|
|
|
|
var emotes = JsonSerializer.Deserialize<IEnumerable<EmoteInfo>>(obj.Data.ToString(), _options);
|
|
|
|
if (emotes == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
var emoteDb = _serviceProvider.GetRequiredService<EmoteDatabase>();
|
|
|
|
var count = 0;
|
|
|
|
foreach (var emote in emotes)
|
|
|
|
{
|
|
|
|
if (emoteDb.Get(emote.Name) == null)
|
|
|
|
{
|
|
|
|
emoteDb.Add(emote.Name, emote.Id);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_logger.Information($"Fetched {count} emotes from various sources.");
|
|
|
|
}
|
|
|
|
else if (obj.Request.Type == "update_tts_voice_state")
|
|
|
|
{
|
|
|
|
_logger.Verbose("Updating TTS voice states.");
|
|
|
|
string voiceId = obj.Request.Data["voice"].ToString();
|
|
|
|
bool state = obj.Request.Data["state"].ToString() == "true";
|
|
|
|
|
|
|
|
if (!context.VoicesAvailable.TryGetValue(voiceId, out string voiceName) || voiceName == null)
|
|
|
|
{
|
|
|
|
_logger.Warning($"Failed to find voice [id: {voiceId}]");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state)
|
|
|
|
context.VoicesEnabled.Add(voiceId);
|
|
|
|
else
|
|
|
|
context.VoicesEnabled.Remove(voiceId);
|
|
|
|
_logger.Information($"Updated voice state [voice: {voiceName}][new state: {(state ? "enabled" : "disabled")}]");
|
2024-03-15 08:27:35 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|