Proxy messages with a mention before tags

This commit is contained in:
Ske 2019-06-27 10:38:45 +02:00
parent 53037f7d52
commit 7eeaea39fe
4 changed files with 32 additions and 10 deletions

View File

@ -83,16 +83,14 @@ namespace PluralKit.Bot
private IServiceProvider _services; private IServiceProvider _services;
private DiscordSocketClient _client; private DiscordSocketClient _client;
private CommandService _commands; private CommandService _commands;
private IDbConnection _connection;
private ProxyService _proxy; private ProxyService _proxy;
private Timer _updateTimer; private Timer _updateTimer;
public Bot(IServiceProvider services, IDiscordClient client, CommandService commands, IDbConnection connection, ProxyService proxy) public Bot(IServiceProvider services, IDiscordClient client, CommandService commands, ProxyService proxy)
{ {
this._services = services; this._services = services;
this._client = client as DiscordSocketClient; this._client = client as DiscordSocketClient;
this._commands = commands; this._commands = commands;
this._connection = connection;
this._proxy = proxy; this._proxy = proxy;
} }
@ -120,7 +118,7 @@ namespace PluralKit.Bot
private async Task Ready() private async Task Ready()
{ {
_updateTimer = new Timer((_) => this.UpdatePeriodic(), null, 0, 60*1000); _updateTimer = new Timer((_) => UpdatePeriodic(), null, 0, 60*1000);
Console.WriteLine($"Shard #{_client.ShardId} connected to {_client.Guilds.Sum(g => g.Channels.Count)} channels in {_client.Guilds.Count} guilds."); Console.WriteLine($"Shard #{_client.ShardId} connected to {_client.Guilds.Sum(g => g.Channels.Count)} channels in {_client.Guilds.Count} guilds.");
Console.WriteLine($"PluralKit started as {_client.CurrentUser.Username}#{_client.CurrentUser.Discriminator} ({_client.CurrentUser.Id})."); Console.WriteLine($"PluralKit started as {_client.CurrentUser.Username}#{_client.CurrentUser.Discriminator} ({_client.CurrentUser.Id}).");
@ -170,8 +168,9 @@ namespace PluralKit.Bot
// If it does, fetch the sender's system (because most commands need that) into the context, // If it does, fetch the sender's system (because most commands need that) into the context,
// and start command execution // and start command execution
// Note system may be null if user has no system, hence `OrDefault` // Note system may be null if user has no system, hence `OrDefault`
var system = await _connection.QueryFirstOrDefaultAsync<PKSystem>("select systems.* from systems, accounts where accounts.uid = @Id and systems.id = accounts.system", new { Id = arg.Author.Id }); var connection = serviceScope.ServiceProvider.GetService<IDbConnection>();
await _commands.ExecuteAsync(new PKCommandContext(_client, arg, _connection, system), argPos, serviceScope.ServiceProvider); var system = await connection.QueryFirstOrDefaultAsync<PKSystem>("select systems.* from systems, accounts where accounts.uid = @Id and systems.id = accounts.system", new { Id = arg.Author.Id });
await _commands.ExecuteAsync(new PKCommandContext(_client, arg, connection, system), argPos, serviceScope.ServiceProvider);
} }
else else
{ {

View File

@ -67,6 +67,7 @@ namespace PluralKit.Bot {
} }
var msg = await ctx.Channel.SendMessageAsync(embed: MakeEmbedForPage(0)); var msg = await ctx.Channel.SendMessageAsync(embed: MakeEmbedForPage(0));
if (pageCount == 1) return; // If we only have one page, don't bother with the reaction/pagination logic, lol
var botEmojis = new[] { new Emoji("\u23EA"), new Emoji("\u2B05"), new Emoji("\u27A1"), new Emoji("\u23E9"), new Emoji(Emojis.Error) }; var botEmojis = new[] { new Emoji("\u23EA"), new Emoji("\u2B05"), new Emoji("\u27A1"), new Emoji("\u23E9"), new Emoji(Emojis.Error) };
await msg.AddReactionsAsync(botEmojis); await msg.AddReactionsAsync(botEmojis);

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
@ -7,7 +6,6 @@ using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapper; using Dapper;
using Discord; using Discord;
using Discord.Rest;
using Discord.Webhook; using Discord.Webhook;
using Discord.WebSocket; using Discord.WebSocket;
@ -45,8 +43,18 @@ namespace PluralKit.Bot
_embeds = embeds; _embeds = embeds;
} }
private ProxyMatch GetProxyTagMatch(string message, IEnumerable<ProxyDatabaseResult> potentials) { private ProxyMatch GetProxyTagMatch(string message, IEnumerable<ProxyDatabaseResult> potentials)
// TODO: add detection of leading @mention {
// If the message starts with a @mention, and then proceeds to have proxy tags,
// extract the mention and place it inside the inner message
// eg. @Ske [text] => [@Ske text]
int matchStartPosition = 0;
string leadingMention = null;
if (Utils.HasMentionPrefix(message, ref matchStartPosition))
{
leadingMention = message.Substring(0, matchStartPosition);
message = message.Substring(matchStartPosition);
}
// Sort by specificity (ProxyString length desc = prefix+suffix length desc = inner message asc = more specific proxy first!) // 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); var ordered = potentials.OrderByDescending(p => p.Member.ProxyString.Length);
@ -59,9 +67,11 @@ namespace PluralKit.Bot
if (message.StartsWith(prefix) && message.EndsWith(suffix)) { if (message.StartsWith(prefix) && message.EndsWith(suffix)) {
var inner = message.Substring(prefix.Length, message.Length - prefix.Length - suffix.Length); var inner = message.Substring(prefix.Length, message.Length - prefix.Length - suffix.Length);
if (leadingMention != null) inner = $"{leadingMention} {inner}";
return new ProxyMatch { Member = potential.Member, System = potential.System, InnerText = inner }; return new ProxyMatch { Member = potential.Member, System = potential.System, InnerText = inner };
} }
} }
return null; return null;
} }

View File

@ -69,6 +69,18 @@ namespace PluralKit.Bot
throw Errors.AvatarDimensionsTooLarge(image.Width, image.Height); throw Errors.AvatarDimensionsTooLarge(image.Width, image.Height);
} }
} }
public static bool HasMentionPrefix(string content, ref int argPos)
{
// Roughly ported from Discord.Commands.MessageExtensions.HasMentionPrefix
if (string.IsNullOrEmpty(content) || content.Length <= 3 || (content[0] != '<' || content[1] != '@'))
return false;
int num = content.IndexOf('>');
if (num == -1 || content.Length < num + 2 || content[num + 1] != ' ' || !MentionUtils.TryParseUser(content.Substring(0, num + 1), out _))
return false;
argPos = num + 2;
return true;
}
} }
class PKSystemTypeReader : TypeReader class PKSystemTypeReader : TypeReader