Skip to content

Commit

Permalink
dynamic aliases: hacky dual-core support
Browse files Browse the repository at this point in the history
  • Loading branch information
Felk committed Oct 17, 2024
1 parent a96938e commit d261025
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 20 deletions.
8 changes: 8 additions & 0 deletions TPP.Core/Chat/ICommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Threading.Tasks;

namespace TPP.Core.Chat;

public interface ICommandHandler
{
public Task ProcessIncomingMessage(IChat chat, Message message);
}
6 changes: 3 additions & 3 deletions TPP.Core/Modes/ModeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

namespace TPP.Core.Modes
{
public sealed class ModeBase : IWithLifecycle
public sealed class ModeBase : IWithLifecycle, ICommandHandler
{
private static readonly Role[] ExemptionRoles = { Role.Operator, Role.Moderator, Role.ModbotExempt };

Expand Down Expand Up @@ -83,7 +83,7 @@ public ModeBase(
c => Setups.SetUpCommandProcessor(loggerFactory, baseConfig, argsParser, repos, stopToken,
muteInputsToken, messageSender: c,
chatModeChanger: c as IChatModeChanger, executor: c as IExecutor,
pokedexData.KnownSpecies, transmuter));
pokedexData.KnownSpecies, transmuter, this));

_outgoingMessagequeueRepo = repos.OutgoingMessagequeueRepo;
_messagelogRepo = repos.MessagelogRepo;
Expand Down Expand Up @@ -170,7 +170,7 @@ private void MessageReceived(object? sender, MessageEventArgs e)

private static readonly CaseInsensitiveImmutableHashSet CoStreamAllowedCommands =
new(["left", "right"]);
private async Task ProcessIncomingMessage(IChat chat, Message message)
public async Task ProcessIncomingMessage(IChat chat, Message message)
{
Instant now = _clock.GetCurrentInstant();
await _messagelogRepo.LogChat(
Expand Down
68 changes: 51 additions & 17 deletions TPP.Core/Setups.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -105,7 +106,8 @@ public static CommandProcessor SetUpCommandProcessor(
IChatModeChanger? chatModeChanger,
IExecutor? executor,
IImmutableSet<PkmnSpecies> knownSpecies,
ITransmuter transmuter)
ITransmuter transmuter,
ICommandHandler commandHandler)
{
var commandProcessor = new CommandProcessor(
loggerFactory.CreateLogger<CommandProcessor>(),
Expand Down Expand Up @@ -170,7 +172,8 @@ public static CommandProcessor SetUpCommandProcessor(
commandProcessor.InstallCommand(command);
}
SetUpDynamicCommands(loggerFactory.CreateLogger("setups"), commandProcessor, databases.ResponseCommandRepo);
SetUpDynamicAliases(loggerFactory.CreateLogger("setups"), commandProcessor, databases.CommandAliasRepo);
SetUpDynamicAliases(loggerFactory.CreateLogger("setups"), commandProcessor, databases.CommandAliasRepo,
commandHandler);
return commandProcessor;
}

Expand Down Expand Up @@ -315,34 +318,65 @@ void UninstallCommand(string commandName)
}

private static void SetUpDynamicAliases(
ILogger logger, CommandProcessor commandProcessor, ICommandAliasRepo commandAliasRepo)
ILogger logger, CommandProcessor commandProcessor, ICommandAliasRepo commandAliasRepo,
ICommandHandler commandHandler)
{
IImmutableList<CommandAlias> aliases = commandAliasRepo.GetAliases().Result;

HashSet<string> dynamicallyInstalledAliases = new();
void InstallAlias(CommandAlias alias)
{
Command? existing = commandProcessor.FindCommand(alias.Alias);
Command? targetCommand = commandProcessor.FindCommand(alias.TargetCommand);
if (existing != null)
{
logger.LogWarning(
"not installing dynamic command alias '{Command}' " +
"because it conflicts with an existing command", alias.Alias);
return;
}
else if (targetCommand == null)
{
logger.LogWarning(
"not installing dynamic command alias '{Command}' " +
"because the target command '{TargetCommand}' does not exist", alias.Alias, alias.TargetCommand);
}
else
{
var aliasCommand = new Command(alias.Alias, targetCommand.Value.Execution)
{ Description = targetCommand.Value.Description };
commandProcessor.InstallCommand(aliasCommand.WithFixedArgs(alias.FixedArgs));
dynamicallyInstalledAliases.Add(alias.Alias);
}
// If we didn't want to be able to also alias to old-core commands, we could just look up the target
// command and execute it directly, like this:
//
// Command? targetCommand = commandProcessor.FindCommand(alias.TargetCommand);
// if (targetCommand == null)
// {
// logger.LogWarning(
// "not installing dynamic command alias '{Command}' " +
// "because the target command '{TargetCommand}' does not exist", alias.Alias, alias.TargetCommand);
// return;
// }
// var aliasCommand = new Command(alias.Alias, targetCommand.Value.Execution)
// { Description = targetCommand.Value.Description };
// commandProcessor.InstallCommand(aliasCommand.WithFixedArgs(alias.FixedArgs));
// dynamicallyInstalledAliases.Add(alias.Alias);
//
// Unfortunately, we do want old-core support, so we have to take a lengthy detour:
// Assemble a brand-new message that has the alias resolved manually,
// and run that through the entire processing chain.

string aliasReplacement = string.Join(' ', [alias.TargetCommand, ..alias.FixedArgs]);
var aliasCommand = new Command(alias.Alias, async ctx =>
{
string messageTextWithAliasResolved =
new Regex("(?<=!?)" + Regex.Escape(alias.Alias), RegexOptions.IgnoreCase)
.Replace(ctx.Message.MessageText, aliasReplacement, 1);
string ircTextWithAliasResolved =
new Regex("(?<=.*? (?:PRIVMSG|WHISPER) .*? :!?)" + Regex.Escape(alias.Alias), RegexOptions.IgnoreCase)
.Replace(ctx.Message.RawIrcMessage, aliasReplacement, 1);
var messageWithAliasResolved = new Message(
ctx.Message.User,
messageTextWithAliasResolved,
ctx.Message.MessageSource,
ircTextWithAliasResolved
);
await commandHandler.ProcessIncomingMessage(ctx.Source!, messageWithAliasResolved);
return new CommandResult();
})
{ Description = "Alias for: " + aliasReplacement };

commandProcessor.InstallCommand(aliasCommand);
dynamicallyInstalledAliases.Add(alias.Alias);
}
void UninstallAlias(string aliasName)
{
Expand Down

0 comments on commit d261025

Please sign in to comment.