From 850c09cfff8c6887042eaa95fccd97799433c8b7 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 3 Dec 2024 02:39:27 +0000 Subject: [PATCH] Made Veadotube redemptions more user friendly --- Startup.cs | 3 ++ Twitch/Redemptions/RedemptionManager.cs | 36 ++++++++++++--- Veadotube/Handlers/FetchStatesHandler.cs | 34 ++++++++++++++ .../Handlers/IVeadotubeMessageHandler.cs | 8 ++++ Veadotube/VeadoMessage.cs | 4 +- Veadotube/VeadoSocketClient.cs | 46 ++++++++++++++++--- 6 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 Veadotube/Handlers/FetchStatesHandler.cs create mode 100644 Veadotube/Handlers/IVeadotubeMessageHandler.cs diff --git a/Startup.cs b/Startup.cs index 61c8b0d..7338711 100644 --- a/Startup.cs +++ b/Startup.cs @@ -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, SevenMessageTypeManag s.AddKeyedSingleton, SevenSocketClient>("7tv"); // Veadotube +s.AddKeyedSingleton("veadotube"); + s.AddKeyedSingleton, VeadoMessageTypeManager>("veadotube"); s.AddKeyedSingleton, VeadoSocketClient>("veadotube"); diff --git a/Twitch/Redemptions/RedemptionManager.cs b/Twitch/Redemptions/RedemptionManager.cs index 0472de1..f5de744 100644 --- a/Twitch/Redemptions/RedemptionManager.cs +++ b/Twitch/Redemptions/RedemptionManager.cs @@ -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; diff --git a/Veadotube/Handlers/FetchStatesHandler.cs b/Veadotube/Handlers/FetchStatesHandler.cs new file mode 100644 index 0000000..d8360cb --- /dev/null +++ b/Veadotube/Handlers/FetchStatesHandler.cs @@ -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(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; + } + } +} \ No newline at end of file diff --git a/Veadotube/Handlers/IVeadotubeMessageHandler.cs b/Veadotube/Handlers/IVeadotubeMessageHandler.cs new file mode 100644 index 0000000..98482c5 --- /dev/null +++ b/Veadotube/Handlers/IVeadotubeMessageHandler.cs @@ -0,0 +1,8 @@ +namespace TwitchChatTTS.Veadotube.Handlers +{ + public interface IVeadotubeMessageHandler + { + string Name { get; } + Task Handle(VeadoSocketClient client, VeadoPayloadMessage message); + } +} \ No newline at end of file diff --git a/Veadotube/VeadoMessage.cs b/Veadotube/VeadoMessage.cs index 20a6d15..c6f34ad 100644 --- a/Veadotube/VeadoMessage.cs +++ b/Veadotube/VeadoMessage.cs @@ -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 Entries { get; set; } + public IEnumerable States { get; set; } } public class VeadoNodeStateMessage : VeadoEventMessage { diff --git a/Veadotube/VeadoSocketClient.cs b/Veadotube/VeadoSocketClient.cs index a1bf67d..89a3279 100644 --- a/Veadotube/VeadoSocketClient.cs +++ b/Veadotube/VeadoSocketClient.cs @@ -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 _handlers; + private IDictionary _states; + public bool Connected { get; set; } public bool Identified { get; set; } public bool Streaming { get; set; } public VeadoSocketClient( - [FromKeyedServices("veadotube")] IEnumerable handlers, - [FromKeyedServices("veadotube")] MessageTypeManager typeManager, + [FromKeyedServices("veadotube")] IEnumerable handlers, + //[FromKeyedServices("veadotube")] MessageTypeManager 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(); } protected override async Task Deserialize(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 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(contentAsString, _options); + if (data == null) + { + return; + } + + var payload = JsonSerializer.Deserialize(data.Payload.ToString()!, _options); + + if (_handlers.TryGetValue(payload?.Event ?? string.Empty, out var handler)) + { + await handler.Handle(this, data); + } + return; } } } \ No newline at end of file