Add message lookup and log channel setting commands
This commit is contained in:
		
							
								
								
									
										42
									
								
								PluralKit.Bot/Commands/ModCommands.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								PluralKit.Bot/Commands/ModCommands.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
 | 
			
		||||
namespace PluralKit.Bot.Commands
 | 
			
		||||
{
 | 
			
		||||
    public class ModCommands: ModuleBase<PKCommandContext>
 | 
			
		||||
    {
 | 
			
		||||
        public LogChannelService LogChannels { get; set; }
 | 
			
		||||
        public MessageStore Messages { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        public EmbedService Embeds { get; set; }
 | 
			
		||||
        
 | 
			
		||||
        [Command("log")]
 | 
			
		||||
        [Remarks("log <channel>")]
 | 
			
		||||
        [RequireUserPermission(GuildPermission.ManageGuild, ErrorMessage = "You must have the Manage Server permission to use this command.")]
 | 
			
		||||
        [RequireContext(ContextType.Guild, ErrorMessage = "This command can not be run in a DM.")]
 | 
			
		||||
        public async Task SetLogChannel(ITextChannel channel = null)
 | 
			
		||||
        {
 | 
			
		||||
            await LogChannels.SetLogChannel(Context.Guild, channel);
 | 
			
		||||
 | 
			
		||||
            if (channel != null)
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{Emojis.Success} Proxy logging channel set to #{channel.Name}.");
 | 
			
		||||
            else
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{Emojis.Success} Proxy logging channel cleared.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Command("message")]
 | 
			
		||||
        [Remarks("message <messageid>")]
 | 
			
		||||
        public async Task GetMessage(ulong messageId)
 | 
			
		||||
        {
 | 
			
		||||
            var message = await Messages.Get(messageId);
 | 
			
		||||
            if (message == null) throw Errors.MessageNotFound(messageId);
 | 
			
		||||
 | 
			
		||||
            await Context.Channel.SendMessageAsync(embed: await Embeds.CreateMessageInfoEmbed(messageId));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Command("message")]
 | 
			
		||||
        [Remarks("message <messageid>")]
 | 
			
		||||
        public async Task GetMessage(IMessage msg) => await GetMessage(msg.Id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -64,5 +64,6 @@ namespace PluralKit.Bot {
 | 
			
		||||
        public static PKError NoImportFilePassed => new PKError("You must either pass an URL to a file as a command parameter, or as an attachment to the message containing the command.");
 | 
			
		||||
        public static PKError InvalidImportFile => new PKError("Imported data file invalid. Make sure this is a .json file directly exported from PluralKit or Tupperbox.");
 | 
			
		||||
        public static PKError ImportCancelled => new PKError("Import cancelled.");
 | 
			
		||||
        public static PKError MessageNotFound(ulong id) => new PKError($"Message with ID '{id}' not found. Are you sure it's a message proxied by PluralKit?");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -10,14 +10,16 @@ namespace PluralKit.Bot {
 | 
			
		||||
        private SystemStore _systems;
 | 
			
		||||
        private MemberStore _members;
 | 
			
		||||
        private SwitchStore _switches;
 | 
			
		||||
        private MessageStore _messages;
 | 
			
		||||
        private IDiscordClient _client;
 | 
			
		||||
 | 
			
		||||
        public EmbedService(SystemStore systems, MemberStore members, IDiscordClient client, SwitchStore switches)
 | 
			
		||||
        public EmbedService(SystemStore systems, MemberStore members, IDiscordClient client, SwitchStore switches, MessageStore messages)
 | 
			
		||||
        {
 | 
			
		||||
            _systems = systems;
 | 
			
		||||
            _members = members;
 | 
			
		||||
            _client = client;
 | 
			
		||||
            _switches = switches;
 | 
			
		||||
            _messages = messages;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<Embed> CreateSystemEmbed(PKSystem system) {
 | 
			
		||||
@@ -117,5 +119,23 @@ namespace PluralKit.Bot {
 | 
			
		||||
                .WithDescription(outputStr)
 | 
			
		||||
                .Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<Embed> CreateMessageInfoEmbed(ulong messageId)
 | 
			
		||||
        {
 | 
			
		||||
            var msg = await _messages.Get(messageId);
 | 
			
		||||
            var channel = (ITextChannel) await _client.GetChannelAsync(msg.Message.Channel);
 | 
			
		||||
            var serverMsg = await channel.GetMessageAsync(msg.Message.Mid);
 | 
			
		||||
 | 
			
		||||
            var memberStr = $"{msg.Member.Name} (`{msg.Member.Hid}`)";
 | 
			
		||||
            if (msg.Member.Pronouns != null) memberStr += $"\n*(pronouns: **{msg.Member.Pronouns}**)*";
 | 
			
		||||
            
 | 
			
		||||
            return new EmbedBuilder()
 | 
			
		||||
                .WithAuthor(msg.Member.Name, msg.Member.AvatarUrl)
 | 
			
		||||
                .WithDescription(serverMsg.Content)
 | 
			
		||||
                .AddField("System", msg.System.Name != null ? $"{msg.System.Name} (`{msg.System.Hid}`)" : $"`{msg.System.Hid}`", true)
 | 
			
		||||
                .AddField("Member", memberStr, true)
 | 
			
		||||
                .WithTimestamp(SnowflakeUtils.FromSnowflake(msg.Message.Mid))
 | 
			
		||||
                .Build();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,12 +4,12 @@ using Dapper;
 | 
			
		||||
using Discord;
 | 
			
		||||
 | 
			
		||||
namespace PluralKit.Bot {
 | 
			
		||||
    class ServerDefinition {
 | 
			
		||||
        public ulong Id;
 | 
			
		||||
        public ulong LogChannel;
 | 
			
		||||
    public class ServerDefinition {
 | 
			
		||||
        public ulong Id { get; set; }
 | 
			
		||||
        public ulong LogChannel { get; set; } 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class LogChannelService {
 | 
			
		||||
    public class LogChannelService {
 | 
			
		||||
        private IDiscordClient _client;
 | 
			
		||||
        private IDbConnection _connection;
 | 
			
		||||
        private EmbedService _embed;
 | 
			
		||||
@@ -30,7 +30,7 @@ namespace PluralKit.Bot {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<ITextChannel> GetLogChannel(IGuild guild) {
 | 
			
		||||
            var server = await _connection.QueryFirstAsync<ServerDefinition>("select * from servers where id = @Id", new { Id = guild.Id });
 | 
			
		||||
            var server = await _connection.QueryFirstOrDefaultAsync<ServerDefinition>("select * from servers where id = @Id", new { Id = guild.Id });
 | 
			
		||||
            if (server == null) return null;
 | 
			
		||||
            return await _client.GetChannelAsync(server.LogChannel) as ITextChannel;
 | 
			
		||||
        }
 | 
			
		||||
@@ -41,7 +41,7 @@ namespace PluralKit.Bot {
 | 
			
		||||
                LogChannel = newLogChannel.Id
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            await _connection.ExecuteAsync("insert into servers(id, log_channel) values (@Id, @LogChannel) on conflict (id) do update set log_channel = @LogChannel", def);
 | 
			
		||||
            await _connection.QueryAsync("insert into servers (id, log_channel) values (@Id, @LogChannel)", def);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -49,7 +49,10 @@ namespace PluralKit.Bot
 | 
			
		||||
 | 
			
		||||
            // Sort by specificity (ProxyString length desc = prefix+suffix length desc = inner message asc = more specific proxy first!)
 | 
			
		||||
            var ordered = potentials.OrderByDescending(p => p.Member.ProxyString.Length);
 | 
			
		||||
            foreach (var potential in ordered) {
 | 
			
		||||
            foreach (var potential in ordered)
 | 
			
		||||
            {
 | 
			
		||||
                if (potential.Member.Prefix == null && potential.Member.Suffix != null) continue;
 | 
			
		||||
                
 | 
			
		||||
                var prefix = potential.Member.Prefix ?? "";
 | 
			
		||||
                var suffix = potential.Member.Suffix ?? "";
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +65,7 @@ namespace PluralKit.Bot
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task HandleMessageAsync(IMessage message) {
 | 
			
		||||
            var results = await _connection.QueryAsync<PKMember, PKSystem, ProxyDatabaseResult>("select members.*, systems.* from members, systems, accounts where members.system = systems.id and accounts.system = systems.id and accounts.uid = @Uid and (members.prefix != null or members.suffix != null)", (member, system) => new ProxyDatabaseResult { Member = member, System = system }, new { Uid = message.Author.Id });
 | 
			
		||||
            var results = await _connection.QueryAsync<PKMember, PKSystem, ProxyDatabaseResult>("select members.*, systems.* from members, systems, accounts where members.system = systems.id and accounts.system = systems.id and accounts.uid = @Uid", (member, system) => new ProxyDatabaseResult { Member = member, System = system }, new { Uid = message.Author.Id });
 | 
			
		||||
 | 
			
		||||
            // Find a member with proxy tags matching the message
 | 
			
		||||
            var match = GetProxyTagMatch(message.Content, results);
 | 
			
		||||
@@ -105,7 +108,7 @@ namespace PluralKit.Bot
 | 
			
		||||
            if (storedMessage == null) return; // (if we can't, that's ok, no worries)
 | 
			
		||||
 | 
			
		||||
            // Make sure it's the actual sender of that message deleting the message
 | 
			
		||||
            if (storedMessage.SenderId != reaction.UserId) return;
 | 
			
		||||
            if (storedMessage.Message.Sender != reaction.UserId) return;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                // Then, fetch the Discord message and delete that
 | 
			
		||||
 
 | 
			
		||||
@@ -114,10 +114,15 @@ namespace PluralKit {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class MessageStore {
 | 
			
		||||
        public class StoredMessage {
 | 
			
		||||
        public struct PKMessage
 | 
			
		||||
        {
 | 
			
		||||
            public ulong Mid;
 | 
			
		||||
            public ulong ChannelId;
 | 
			
		||||
            public ulong SenderId;
 | 
			
		||||
            public ulong Channel;
 | 
			
		||||
            public ulong Sender;
 | 
			
		||||
        }
 | 
			
		||||
        public class StoredMessage
 | 
			
		||||
        {
 | 
			
		||||
            public PKMessage Message;
 | 
			
		||||
            public PKMember Member;
 | 
			
		||||
            public PKSystem System;
 | 
			
		||||
        }
 | 
			
		||||
@@ -137,11 +142,13 @@ namespace PluralKit {
 | 
			
		||||
            });      
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<StoredMessage> Get(ulong id) {
 | 
			
		||||
            return (await _connection.QueryAsync<StoredMessage, PKMember, PKSystem, StoredMessage>("select * from messages, members, systems where mid = @Id and messages.member = members.id and systems.id = members.system", (msg, member, system) => {
 | 
			
		||||
                msg.System = system;
 | 
			
		||||
                msg.Member = member;
 | 
			
		||||
                return msg;
 | 
			
		||||
        public async Task<StoredMessage> Get(ulong id)
 | 
			
		||||
        {
 | 
			
		||||
            return (await _connection.QueryAsync<PKMessage, PKMember, PKSystem, StoredMessage>("select messages.*, members.*, systems.* from messages, members, systems where mid = @Id and messages.member = members.id and systems.id = members.system", (msg, member, system) => new StoredMessage
 | 
			
		||||
            {
 | 
			
		||||
                Message = msg,
 | 
			
		||||
                System = system,
 | 
			
		||||
                Member = member
 | 
			
		||||
            }, new { Id = id })).FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user