PluralKit/PluralKit.Bot/CommandSystem/Context.cs

178 lines
6.9 KiB
C#
Raw Normal View History

2019-10-05 05:41:00 +00:00
using System;
using System.Collections.Generic;
2019-10-05 05:41:00 +00:00
using System.Threading.Tasks;
2019-12-21 20:51:41 +00:00
using App.Metrics;
2020-01-26 00:27:45 +00:00
using Autofac;
using DSharpPlus;
using DSharpPlus.Entities;
using Myriad.Cache;
2020-12-22 12:15:26 +00:00
using Myriad.Extensions;
using Myriad.Gateway;
2020-12-24 13:52:44 +00:00
using Myriad.Rest.Types;
using Myriad.Rest.Types.Requests;
2020-12-22 12:15:26 +00:00
using Myriad.Types;
using PluralKit.Core;
2019-10-05 05:41:00 +00:00
using DiscordApiClient = Myriad.Rest.DiscordApiClient;
2020-12-22 12:15:26 +00:00
namespace PluralKit.Bot
2019-10-05 05:41:00 +00:00
{
public class Context
{
2020-08-29 11:46:27 +00:00
private readonly ILifetimeScope _provider;
2019-10-05 05:41:00 +00:00
2020-04-24 19:50:28 +00:00
private readonly DiscordRestClient _rest;
private readonly DiscordApiClient _newRest;
2019-10-05 05:41:00 +00:00
private readonly DiscordShardedClient _client;
2020-12-22 12:15:26 +00:00
private readonly DiscordClient _shard = null;
private readonly Shard _shardNew;
private readonly Guild? _guild;
private readonly Channel _channel;
private readonly DiscordMessage _message = null;
2020-12-24 13:52:44 +00:00
private readonly MessageCreateEvent _messageNew;
2019-10-05 05:41:00 +00:00
private readonly Parameters _parameters;
private readonly MessageContext _messageContext;
2020-12-22 12:15:26 +00:00
private readonly PermissionSet _botPermissions;
private readonly PermissionSet _userPermissions;
2019-10-05 05:41:00 +00:00
2020-06-29 21:51:12 +00:00
private readonly IDatabase _db;
2020-08-29 11:46:27 +00:00
private readonly ModelRepository _repo;
2019-10-05 05:41:00 +00:00
private readonly PKSystem _senderSystem;
2019-12-21 20:51:41 +00:00
private readonly IMetrics _metrics;
2020-10-23 10:18:28 +00:00
private readonly CommandMessageService _commandMessageService;
private readonly IDiscordCache _cache;
2019-10-05 05:41:00 +00:00
private Command _currentCommand;
2020-12-22 12:15:26 +00:00
public Context(ILifetimeScope provider, Shard shard, Guild? guild, Channel channel, MessageCreateEvent message, int commandParseOffset,
PKSystem senderSystem, MessageContext messageContext, PermissionSet botPermissions)
2019-10-05 05:41:00 +00:00
{
2020-04-24 19:50:28 +00:00
_rest = provider.Resolve<DiscordRestClient>();
2020-01-26 00:27:45 +00:00
_client = provider.Resolve<DiscordShardedClient>();
2020-12-22 12:15:26 +00:00
_messageNew = message;
_shardNew = shard;
_guild = guild;
_channel = channel;
2019-10-05 05:41:00 +00:00
_senderSystem = senderSystem;
_messageContext = messageContext;
_cache = provider.Resolve<IDiscordCache>();
2020-06-29 21:51:12 +00:00
_db = provider.Resolve<IDatabase>();
2020-08-29 11:46:27 +00:00
_repo = provider.Resolve<ModelRepository>();
2020-01-26 00:27:45 +00:00
_metrics = provider.Resolve<IMetrics>();
2019-10-05 05:41:00 +00:00
_provider = provider;
2020-10-23 10:18:28 +00:00
_commandMessageService = provider.Resolve<CommandMessageService>();
2019-10-05 05:41:00 +00:00
_parameters = new Parameters(message.Content.Substring(commandParseOffset));
_newRest = provider.Resolve<DiscordApiClient>();
2020-12-22 12:15:26 +00:00
_botPermissions = botPermissions;
_userPermissions = _cache.PermissionsFor(message);
2019-10-05 05:41:00 +00:00
}
public IDiscordCache Cache => _cache;
public DiscordUser Author => _message.Author;
public DiscordChannel Channel => _message.Channel;
2020-12-22 12:15:26 +00:00
public Channel ChannelNew => _channel;
public User AuthorNew => _messageNew.Author;
2020-12-24 13:52:44 +00:00
public GuildMemberPartial MemberNew => _messageNew.Member;
public DiscordMessage Message => _message;
2020-12-22 12:15:26 +00:00
public Message MessageNew => _messageNew;
public DiscordGuild Guild => _message.Channel.Guild;
2020-12-22 12:15:26 +00:00
public Guild GuildNew => _guild;
public DiscordClient Shard => _shard;
2019-10-05 05:41:00 +00:00
public DiscordShardedClient Client => _client;
public MessageContext MessageContext => _messageContext;
2020-04-24 19:50:28 +00:00
2020-12-22 12:15:26 +00:00
public PermissionSet BotPermissions => _botPermissions;
public PermissionSet UserPermissions => _userPermissions;
2020-04-24 19:50:28 +00:00
public DiscordRestClient Rest => _rest;
2020-12-24 13:52:44 +00:00
public DiscordApiClient RestNew => _newRest;
2020-04-24 19:50:28 +00:00
2019-10-05 05:41:00 +00:00
public PKSystem System => _senderSystem;
public Parameters Parameters => _parameters;
2019-10-05 05:41:00 +00:00
2020-06-29 21:51:12 +00:00
internal IDatabase Database => _db;
2020-08-29 11:46:27 +00:00
internal ModelRepository Repository => _repo;
2019-10-05 05:41:00 +00:00
public Task<DiscordMessage> Reply(string text, DiscordEmbed embed,
IEnumerable<IMention>? mentions = null)
{
2020-12-24 13:52:44 +00:00
throw new NotImplementedException();
}
public Task<DiscordMessage> Reply(DiscordEmbed embed,
IEnumerable<IMention>? mentions = null)
{
2020-12-24 13:52:44 +00:00
throw new NotImplementedException();
}
2020-12-24 13:52:44 +00:00
public async Task<Message> Reply(string text = null, Embed embed = null, AllowedMentions? mentions = null)
{
if (!BotPermissions.HasFlag(PermissionSet.SendMessages))
// Will be "swallowed" during the error handler anyway, this message is never shown.
throw new PKError("PluralKit does not have permission to send messages in this channel.");
if (embed != null && !BotPermissions.HasFlag(PermissionSet.EmbedLinks))
throw new PKError("PluralKit does not have permission to send embeds in this channel. Please ensure I have the **Embed Links** permission enabled.");
var msg = await _newRest.CreateMessage(_channel.Id, new MessageRequest
{
Content = text,
2020-12-24 13:52:44 +00:00
Embed = embed,
AllowedMentions = mentions
});
2020-12-24 13:52:44 +00:00
// TODO: mentions should default to empty and not null?
2020-10-23 10:18:28 +00:00
if (embed != null)
{
// Sensitive information that might want to be deleted by :x: reaction is typically in an embed format (member cards, for example)
// This may need to be changed at some point but works well enough for now
await _commandMessageService.RegisterMessage(msg.Id, AuthorNew.Id);
2020-10-23 10:18:28 +00:00
}
2020-12-24 13:52:44 +00:00
return msg;
}
2020-01-11 15:49:20 +00:00
2019-10-05 05:41:00 +00:00
public async Task Execute<T>(Command commandDef, Func<T, Task> handler)
{
_currentCommand = commandDef;
try
{
2020-01-26 00:27:45 +00:00
await handler(_provider.Resolve<T>());
2019-12-21 20:51:41 +00:00
_metrics.Measure.Meter.Mark(BotMetrics.CommandsRun);
2019-10-05 05:41:00 +00:00
}
catch (PKSyntaxError e)
{
2019-12-28 11:16:26 +00:00
await Reply($"{Emojis.Error} {e.Message}\n**Command usage:**\n> pk;{commandDef.Usage}");
2019-10-05 05:41:00 +00:00
}
catch (PKError e)
{
await Reply($"{Emojis.Error} {e.Message}");
}
catch (TimeoutException)
{
// Got a complaint the old error was a bit too patronizing. Hopefully this is better?
await Reply($"{Emojis.Error} Operation timed out, sorry. Try again, perhaps?");
}
2019-10-05 05:41:00 +00:00
}
2020-01-11 15:49:20 +00:00
public LookupContext LookupContextFor(PKSystem target) =>
System?.Id == target.Id ? LookupContext.ByOwner : LookupContext.ByNonOwner;
2020-02-27 23:23:54 +00:00
2020-06-14 19:37:04 +00:00
public LookupContext LookupContextFor(SystemId systemId) =>
2020-02-27 23:23:54 +00:00
System?.Id == systemId ? LookupContext.ByOwner : LookupContext.ByNonOwner;
public LookupContext LookupContextFor(PKMember target) =>
System?.Id == target.System ? LookupContext.ByOwner : LookupContext.ByNonOwner;
2020-05-05 14:03:46 +00:00
public IComponentContext Services => _provider;
2019-10-05 05:41:00 +00:00
}
}