Compare commits

..

4 Commits

10 changed files with 127 additions and 21 deletions

View File

@ -62,7 +62,7 @@ namespace TwitchChatTTS.Chat.Messaging
var emoteUsage = GetEmoteUsage(fragments);
var tasks = new List<Task>();
if (_obs.Streaming)
if (_obs.Streaming && _configuration.Twitch?.Slave != true)
{
if (emoteUsage.NewEmotes.Any())
tasks.Add(_hermes.SendEmoteDetails(emoteUsage.NewEmotes));

View File

@ -14,8 +14,8 @@ namespace TwitchChatTTS
}
public class TwitchConfiguration {
public IEnumerable<string>? Channels;
public bool TtsWhenOffline;
public bool Slave;
public string? WebsocketUrl;
public string? ApiUrl;
}

View File

@ -36,6 +36,7 @@ using TwitchChatTTS.Chat.Commands.Limits;
using TwitchChatTTS.Hermes.Socket.Requests;
using TwitchChatTTS.Bus;
using TwitchChatTTS.Veadotube;
using TwitchChatTTS.Veadotube.Handlers;
// dotnet publish -r linux-x64 -p:PublishSingleFile=true --self-contained true
// dotnet publish -r win-x64 -p:PublishSingleFile=true --self-contained true
@ -149,6 +150,8 @@ s.AddKeyedSingleton<MessageTypeManager<IWebSocketHandler>, SevenMessageTypeManag
s.AddKeyedSingleton<SocketClient<WebSocketMessage>, SevenSocketClient>("7tv");
// Veadotube
s.AddKeyedSingleton<IVeadotubeMessageHandler, FetchStatesHandler>("veadotube");
s.AddKeyedSingleton<MessageTypeManager<IWebSocketHandler>, VeadoMessageTypeManager>("veadotube");
s.AddKeyedSingleton<SocketClient<object>, VeadoSocketClient>("veadotube");

7
TTS.cs
View File

@ -21,7 +21,7 @@ namespace TwitchChatTTS
public class TTS : IHostedService
{
public const int MAJOR_VERSION = 4;
public const int MINOR_VERSION = 4;
public const int MINOR_VERSION = 5;
private readonly User _user;
private readonly HermesApiClient _hermesApiClient;
@ -89,9 +89,10 @@ namespace TwitchChatTTS
var hermesVersion = await _hermesApiClient.GetLatestTTSVersion();
if (hermesVersion == null)
{
_logger.Warning("Failed to fetch latest TTS version. Skipping version check.");
_logger.Error("Failed to fetch latest TTS version. Something went wrong.");
return;
}
else if (hermesVersion.MajorVersion > TTS.MAJOR_VERSION || hermesVersion.MajorVersion == TTS.MAJOR_VERSION && hermesVersion.MinorVersion > TTS.MINOR_VERSION)
if (hermesVersion.MajorVersion > TTS.MAJOR_VERSION || hermesVersion.MajorVersion == TTS.MAJOR_VERSION && hermesVersion.MinorVersion > TTS.MINOR_VERSION)
{
_logger.Information($"A new update for TTS is avaiable! Version {hermesVersion.MajorVersion}.{hermesVersion.MinorVersion} is available at {hermesVersion.Download}");
var changes = hermesVersion.Changelog.Split("\n");

View File

@ -55,6 +55,12 @@ namespace TwitchChatTTS
return;
}
if (DateTime.UtcNow - group.Timestamp > TimeSpan.FromSeconds(60))
{
_logger.Debug("Ignored message due to being in queue for too long.");
continue;
}
FetchMasterAudio(group);
}
catch (COMException e)

View File

@ -52,7 +52,8 @@ namespace TwitchChatTTS.Twitch.Redemptions
_isReady = false;
var topic = _bus.GetTopic("redemptions_initiation");
topic.Subscribe(new ServiceBusObserver(data => {
topic.Subscribe(new ServiceBusObserver(data =>
{
if (data.Value is RedemptionInitiation obj)
Initialize(obj.Redemptions, obj.Actions);
}, _logger));
@ -225,14 +226,35 @@ namespace TwitchChatTTS.Twitch.Redemptions
await _nightbot.ClearQueue();
break;
case "VEADOTUBE_SET_STATE":
await _veado.SetCurrentState(action.Data["state"]);
break;
{
var state = _veado.GetStateId(action.Data["state"]);
if (state == null) {
_logger.Warning($"Could not find the state named '{action.Data["state"]}'.");
break;
}
await _veado.SetCurrentState(state);
break;
}
case "VEADOTUBE_PUSH_STATE":
await _veado.PushState(action.Data["state"]);
break;
{
var state = _veado.GetStateId(action.Data["state"]);
if (state == null) {
_logger.Warning($"Could not find the state named '{action.Data["state"]}'.");
break;
}
await _veado.PushState(state);
break;
}
case "VEADOTUBE_POP_STATE":
await _veado.PopState(action.Data["state"]);
break;
{
var state = _veado.GetStateId(action.Data["state"]);
if (state == null) {
_logger.Warning($"Could not find the state named '{action.Data["state"]}'.");
break;
}
await _veado.PopState(state);
break;
}
default:
_logger.Warning($"Unknown redeemable action has occured. Update needed? [type: {action.Type}][chatter: {senderDisplayName}][chatter id: {senderId}]");
break;

View File

@ -0,0 +1,34 @@
using System.Text.Json;
using Serilog;
namespace TwitchChatTTS.Veadotube.Handlers
{
public class FetchStatesHandler : IVeadotubeMessageHandler
{
private readonly JsonSerializerOptions _options;
private readonly ILogger _logger;
public string Name => "list";
public FetchStatesHandler(JsonSerializerOptions options, ILogger logger)
{
_options = options;
_logger = logger;
}
public Task Handle(VeadoSocketClient client, VeadoPayloadMessage message)
{
_logger.Information("Triggered Veadotube handler.");
var payload = JsonSerializer.Deserialize<VeadoNodeStateListMessage>(message.Payload.ToString()!, _options);
if (payload == null)
{
_logger.Warning("Invalid message received from Veadotube for listing states.");
return Task.CompletedTask;
}
var states = payload.States.ToDictionary(s => s.Name, s => s.Id);
client.UpdateState(states);
return Task.CompletedTask;
}
}
}

View File

@ -0,0 +1,8 @@
namespace TwitchChatTTS.Veadotube.Handlers
{
public interface IVeadotubeMessageHandler
{
string Name { get; }
Task Handle(VeadoSocketClient client, VeadoPayloadMessage message);
}
}

View File

@ -1,5 +1,4 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace TwitchChatTTS.Veadotube
{
@ -8,6 +7,7 @@ namespace TwitchChatTTS.Veadotube
public string Event { get; set; }
public string Type { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public object Payload { get; set; }
}
@ -23,7 +23,7 @@ namespace TwitchChatTTS.Veadotube
}
public class VeadoNodeStateListMessage : VeadoEventMessage {
public IEnumerable<VeadoNodeState> Entries { get; set; }
public IEnumerable<VeadoNodeState> States { get; set; }
}
public class VeadoNodeStateMessage : VeadoEventMessage {

View File

@ -1,4 +1,3 @@
using CommonSocketLibrary.Common;
using CommonSocketLibrary.Abstract;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
@ -6,6 +5,7 @@ using System.Text.Json;
using CommonSocketLibrary.Backoff;
using System.Text;
using System.Net.WebSockets;
using TwitchChatTTS.Veadotube.Handlers;
namespace TwitchChatTTS.Veadotube
{
@ -13,14 +13,17 @@ namespace TwitchChatTTS.Veadotube
{
private VeadoInstanceInfo? Instance;
private IDictionary<string, IVeadotubeMessageHandler> _handlers;
private IDictionary<string, string> _states;
public bool Connected { get; set; }
public bool Identified { get; set; }
public bool Streaming { get; set; }
public VeadoSocketClient(
[FromKeyedServices("veadotube")] IEnumerable<IWebSocketHandler> handlers,
[FromKeyedServices("veadotube")] MessageTypeManager<IWebSocketHandler> typeManager,
[FromKeyedServices("veadotube")] IEnumerable<IVeadotubeMessageHandler> handlers,
//[FromKeyedServices("veadotube")] MessageTypeManager<IVeadotubeMessageHandler> typeManager,
ILogger logger
) : base(logger, new JsonSerializerOptions()
{
@ -28,6 +31,8 @@ namespace TwitchChatTTS.Veadotube
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
})
{
_handlers = handlers.ToDictionary(h => h.Name, h => h);
_states = new Dictionary<string, string>();
}
protected override async Task<T> Deserialize<T>(Stream stream)
@ -43,10 +48,12 @@ namespace TwitchChatTTS.Veadotube
public void Initialize()
{
_logger.Information($"Initializing Veadotube websocket client.");
OnConnected += (sender, e) =>
OnConnected += async (sender, e) =>
{
Connected = true;
_logger.Information("Veadotube websocket client connected.");
await FetchStates();
};
OnDisconnected += async (sender, e) =>
@ -97,6 +104,13 @@ namespace TwitchChatTTS.Veadotube
});
}
public string? GetStateId(string state)
{
if (_states.TryGetValue(state, out var id))
return id;
return null;
}
public async Task SetCurrentState(string stateId)
{
await Send(new VeadoPayloadMessage()
@ -180,6 +194,11 @@ namespace TwitchChatTTS.Veadotube
}
}
public void UpdateState(IDictionary<string, string> states)
{
_states = states;
}
private bool UpdateURL()
{
string path = Environment.ExpandEnvironmentVariables("%userprofile%/.veadotube/instances");
@ -212,11 +231,24 @@ namespace TwitchChatTTS.Veadotube
return false;
}
protected override Task OnResponseReceived(object? content)
protected override async Task OnResponseReceived(object? content)
{
var contentAsString = JsonSerializer.Serialize(content);
var contentAsString = JsonSerializer.Serialize(content, _options);
_logger.Debug("VEADO RX: " + contentAsString);
return Task.CompletedTask;
var data = JsonSerializer.Deserialize<VeadoPayloadMessage>(contentAsString, _options);
if (data == null)
{
return;
}
var payload = JsonSerializer.Deserialize<VeadoEventMessage>(data.Payload.ToString()!, _options);
if (_handlers.TryGetValue(payload?.Event ?? string.Empty, out var handler))
{
await handler.Handle(this, data);
}
return;
}
}
}