Generalized the ChatMessageReader to make it work with ChannelResubscrition. Added connections refresh command.

This commit is contained in:
Tom
2024-08-12 19:45:17 +00:00
parent f503f7c6f4
commit 1d43515fb9
18 changed files with 182 additions and 135 deletions

View File

@ -37,7 +37,8 @@ namespace TwitchChatTTS.Chat.Commands
_logger = logger;
_stack = new Stack<CommandNode>();
Clear();
_root = new CommandNode(new StaticParameter("root", "root"));
_current = _root;
}
@ -201,7 +202,7 @@ namespace TwitchChatTTS.Chat.Commands
public interface ICommandSelector
{
CommandSelectorResult GetBestMatch(string[] args, ChannelChatMessage message);
CommandSelectorResult GetBestMatch(string[] args, TwitchChatFragment[] fragments);
IDictionary<string, CommandParameter> GetNonStaticArguments(string[] args, string path);
}
@ -214,12 +215,12 @@ namespace TwitchChatTTS.Chat.Commands
_root = root;
}
public CommandSelectorResult GetBestMatch(string[] args, ChannelChatMessage message)
public CommandSelectorResult GetBestMatch(string[] args, TwitchChatFragment[] fragments)
{
return GetBestMatch(_root, message, args, null, string.Empty, null);
return GetBestMatch(_root, fragments, args, null, string.Empty, null);
}
private CommandSelectorResult GetBestMatch(CommandNode node, ChannelChatMessage message, IEnumerable<string> args, IChatPartialCommand? match, string path, string[]? permissions)
private CommandSelectorResult GetBestMatch(CommandNode node, TwitchChatFragment[] fragments, IEnumerable<string> args, IChatPartialCommand? match, string path, string[]? permissions)
{
if (node == null || !args.Any())
return new CommandSelectorResult(match, path, permissions);
@ -234,13 +235,13 @@ namespace TwitchChatTTS.Chat.Commands
if (child.Parameter.GetType() == typeof(StaticParameter))
{
if (child.Parameter.Name.ToLower() == argumentLower)
return GetBestMatch(child, message, args.Skip(1), child.Command ?? match, (path.Length == 0 ? string.Empty : path + ".") + child.Parameter.Name.ToLower(), perms);
return GetBestMatch(child, fragments, args.Skip(1), child.Command ?? match, (path.Length == 0 ? string.Empty : path + ".") + child.Parameter.Name.ToLower(), perms);
continue;
}
if ((!child.Parameter.Optional || child.Parameter.Validate(argument, message)) && child.Command != null)
return GetBestMatch(child, message, args.Skip(1), child.Command, (path.Length == 0 ? string.Empty : path + ".") + "*", perms);
if ((!child.Parameter.Optional || child.Parameter.Validate(argument, fragments)) && child.Command != null)
return GetBestMatch(child, fragments, args.Skip(1), child.Command, (path.Length == 0 ? string.Empty : path + ".") + "*", perms);
if (!child.Parameter.Optional)
return GetBestMatch(child, message, args.Skip(1), match, (path.Length == 0 ? string.Empty : path + ".") + "*", permissions);
return GetBestMatch(child, fragments, args.Skip(1), match, (path.Length == 0 ? string.Empty : path + ".") + "*", permissions);
}
return new CommandSelectorResult(match, path, permissions);

View File

@ -59,7 +59,7 @@ namespace TwitchChatTTS.Chat.Commands
string[] args = parts.ToArray();
string com = args.First().ToLower();
CommandSelectorResult selectorResult = _commandSelector.GetBestMatch(args, message);
CommandSelectorResult selectorResult = _commandSelector.GetBestMatch(args, message.Message.Fragments);
if (selectorResult.Command == null)
{
_logger.Warning($"Could not match '{arg}' to any command [chatter: {message.ChatterUserLogin}][chatter id: {message.ChatterUserId}]");
@ -86,7 +86,7 @@ namespace TwitchChatTTS.Chat.Commands
var parameter = entry.Value;
var argument = entry.Key;
// Optional parameters were validated while fetching this command.
if (!parameter.Optional && !parameter.Validate(argument, message))
if (!parameter.Optional && !parameter.Validate(argument, message.Message.Fragments))
{
_logger.Warning($"Command failed due to an argument being invalid [argument name: {parameter.Name}][argument value: {argument}][arguments: {arg}][command type: {command.GetType().Name}][chatter: {message.ChatterUserLogin}][chatter id: {message.ChatterUserId}]");
return ChatCommandResult.Syntax;

View File

@ -13,6 +13,6 @@ namespace TwitchChatTTS.Chat.Commands.Parameters
Optional = optional;
}
public abstract bool Validate(string value, ChannelChatMessage message);
public abstract bool Validate(string value, TwitchChatFragment[] fragments);
}
}

View File

@ -8,9 +8,9 @@ namespace TwitchChatTTS.Chat.Commands.Parameters
{
}
public override bool Validate(string value, ChannelChatMessage message)
public override bool Validate(string value, TwitchChatFragment[] fragments)
{
return value.StartsWith('@') && message.Message.Fragments.Any(f => f.Text == value && f.Mention != null);
return value.StartsWith('@') && fragments.Any(f => f.Text == value && f.Mention != null);
}
}
}

View File

@ -10,7 +10,7 @@ namespace TwitchChatTTS.Chat.Commands.Parameters
{
}
public override bool Validate(string value, ChannelChatMessage message)
public override bool Validate(string value, TwitchChatFragment[] fragments)
{
return _values.Contains(value.ToLower());
}

View File

@ -10,7 +10,7 @@ namespace TwitchChatTTS.Chat.Commands.Parameters
{
}
public override bool Validate(string value, ChannelChatMessage message)
public override bool Validate(string value, TwitchChatFragment[] fragments)
{
return _values.Contains(value.ToLower());
}

View File

@ -13,7 +13,7 @@ namespace TwitchChatTTS.Chat.Commands.Parameters
_value = value.ToLower();
}
public override bool Validate(string value, ChannelChatMessage message)
public override bool Validate(string value, TwitchChatFragment[] fragments)
{
return _value == value.ToLower();
}

View File

@ -13,7 +13,7 @@ namespace TwitchChatTTS.Chat.Commands.Parameters
_user = user;
}
public override bool Validate(string value, ChannelChatMessage message)
public override bool Validate(string value, TwitchChatFragment[] fragments)
{
if (_user.VoicesAvailable == null)
return false;

View File

@ -8,7 +8,7 @@ namespace TwitchChatTTS.Chat.Commands.Parameters
{
}
public override bool Validate(string value, ChannelChatMessage message)
public override bool Validate(string value, TwitchChatFragment[] fragments)
{
return true;
}

View File

@ -4,7 +4,6 @@ using Microsoft.Extensions.DependencyInjection;
using Serilog;
using TwitchChatTTS.Hermes.Socket;
using TwitchChatTTS.OBS.Socket;
using TwitchChatTTS.Twitch.Socket;
using TwitchChatTTS.Twitch.Socket.Messages;
using static TwitchChatTTS.Chat.Commands.TTSCommands;
@ -37,7 +36,8 @@ namespace TwitchChatTTS.Chat.Commands
.CreateStaticInputParameter("default_voice", b => b.CreateCommand(new RefreshTTSDefaultVoice()))
.CreateStaticInputParameter("redemptions", b => b.CreateCommand(new RefreshRedemptions()))
.CreateStaticInputParameter("obs_cache", b => b.CreateCommand(new RefreshObs(_obs, _logger)))
.CreateStaticInputParameter("permissions", b => b.CreateCommand(new RefreshPermissions()));
.CreateStaticInputParameter("permissions", b => b.CreateCommand(new RefreshPermissions()))
.CreateStaticInputParameter("connections", b => b.CreateCommand(new RefreshConnections()));
});
}
@ -113,7 +113,6 @@ namespace TwitchChatTTS.Chat.Commands
private sealed class RefreshPermissions : IChatPartialCommand
{
public bool AcceptCustomPermission { get => true; }
public async Task Execute(IDictionary<string, string> values, ChannelChatMessage message, HermesSocketClient hermes)
@ -121,5 +120,15 @@ namespace TwitchChatTTS.Chat.Commands
await hermes.FetchPermissions();
}
}
private sealed class RefreshConnections : IChatPartialCommand
{
public bool AcceptCustomPermission { get => true; }
public async Task Execute(IDictionary<string, string> values, ChannelChatMessage message, HermesSocketClient hermes)
{
await hermes.FetchConnections();
}
}
}
}