// // ChatCommandInterceptor.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Reflection.Emit; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NosSmooth.Core.Extensions; using NosSmooth.LocalClient; using NosSmooth.Packets.Enums; using NosSmooth.Packets.Enums.Chat; using NosSmooth.Packets.Server.Chat; using Remora.Commands.Services; namespace NosSmooth.ChatCommands; /// /// Handles commands in the chat. /// public class ChatCommandInterceptor : IPacketInterceptor { private readonly CommandService _commandService; private readonly IServiceProvider _serviceProvider; private readonly FeedbackService _feedbackService; private readonly ILogger _logger; private readonly ChatCommandsOptions _options; /// /// Initializes a new instance of the class. /// /// The options. /// The command service. /// The services. /// The feedback service. /// The logger. public ChatCommandInterceptor ( IOptions options, CommandService commandService, IServiceProvider serviceProvider, FeedbackService feedbackService, ILogger logger ) { _commandService = commandService; _serviceProvider = serviceProvider; _feedbackService = feedbackService; _logger = logger; _options = options.Value; } /// public bool InterceptSend(ref string packet) { ReadOnlySpan span = packet; if (span.StartsWith("say ") && span.Slice(4).StartsWith(_options.Prefix)) { var command = span.Slice(4 + _options.Prefix.Length).ToString(); Task.Run(async () => await ExecuteCommand(command)); return false; } return true; } /// public bool InterceptReceive(ref string packet) { return true; } private async Task ExecuteCommand(string command) { try { var preparedResult = await _commandService.TryPrepareCommandAsync(command, _serviceProvider); if (!preparedResult.IsSuccess) { _logger.LogError($"Could not prepare \"{command}\""); _logger.LogResultError(preparedResult); await _feedbackService.SendErrorMessageAsync ($"Could not prepare the given command. {preparedResult.ToFullString()}"); return; } var executeResult = await _commandService.TryExecuteAsync(preparedResult.Entity, _serviceProvider); if (!executeResult.IsSuccess) { _logger.LogError($"Could not execute \"{command}\""); _logger.LogResultError(executeResult); await _feedbackService.SendErrorMessageAsync ($"Could not execute the given command. {executeResult.ToFullString()}"); return; } if (!executeResult.Entity.IsSuccess) { _logger.LogError($"There was an error while handling \"{command}\""); _logger.LogResultError(executeResult.Entity); await _feedbackService.SendErrorMessageAsync ($"Could not execute the given command. {executeResult.Entity.ToFullString()}"); } } catch (Exception e) { _logger.LogError(e, "Could not execute a command"); } } }