Add system linking commands
This commit is contained in:
parent
8b8ec80944
commit
4c6790432b
PluralKit.Bot
PluralKit.Core
@ -130,6 +130,9 @@ namespace PluralKit.Bot
|
||||
await ctx.Message.Channel.SendMessageAsync($"{Emojis.Error} {exception.Message}");
|
||||
} else if (exception is TimeoutException) {
|
||||
await ctx.Message.Channel.SendMessageAsync($"{Emojis.Error} Operation timed out. Try being faster next time :)");
|
||||
} else if (_result is PreconditionResult)
|
||||
{
|
||||
await ctx.Message.Channel.SendMessageAsync($"{Emojis.Error} {_result.ErrorReason}");
|
||||
} else {
|
||||
HandleRuntimeError((_result as ExecuteResult?)?.Exception);
|
||||
}
|
||||
|
50
PluralKit.Bot/Commands/LinkCommands.cs
Normal file
50
PluralKit.Bot/Commands/LinkCommands.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace PluralKit.Bot.Commands
|
||||
{
|
||||
public class LinkCommands: ModuleBase<PKCommandContext>
|
||||
{
|
||||
public SystemStore Systems { get; set; }
|
||||
|
||||
|
||||
[Command("link")]
|
||||
[Remarks("link <account>")]
|
||||
[MustHaveSystem]
|
||||
public async Task LinkSystem(IUser account)
|
||||
{
|
||||
var accountIds = await Systems.GetLinkedAccountIds(Context.SenderSystem);
|
||||
if (accountIds.Contains(account.Id)) throw Errors.AccountAlreadyLinked;
|
||||
|
||||
var existingAccount = await Systems.GetByAccount(account.Id);
|
||||
if (existingAccount != null) throw Errors.AccountInOtherSystem(existingAccount);
|
||||
|
||||
var msg = await Context.Channel.SendMessageAsync(
|
||||
$"{account.Mention}, please confirm the link by clicking the {Emojis.Success} reaction on this message.");
|
||||
if (!await Context.PromptYesNo(msg, user: account)) throw Errors.MemberLinkCancelled;
|
||||
await Systems.Link(Context.SenderSystem, account.Id);
|
||||
await Context.Channel.SendMessageAsync($"{Emojis.Success} Account linked to system.");
|
||||
}
|
||||
|
||||
[Command("unlink")]
|
||||
[Remarks("unlink [account]")]
|
||||
[MustHaveSystem]
|
||||
public async Task UnlinkAccount(IUser account = null)
|
||||
{
|
||||
if (account == null) account = Context.User;
|
||||
|
||||
var accountIds = (await Systems.GetLinkedAccountIds(Context.SenderSystem)).ToList();
|
||||
if (!accountIds.Contains(account.Id)) throw Errors.AccountNotLinked;
|
||||
if (accountIds.Count == 1) throw Errors.UnlinkingLastAccount;
|
||||
|
||||
var msg = await Context.Channel.SendMessageAsync(
|
||||
$"Are you sure you want to unlink {account.Mention} from your system?");
|
||||
if (!await Context.PromptYesNo(msg)) throw Errors.MemberUnlinkCancelled;
|
||||
|
||||
await Systems.Unlink(Context.SenderSystem, account.Id);
|
||||
await Context.Channel.SendMessageAsync($"{Emojis.Success} Account unlinked.");
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace PluralKit.Bot {
|
||||
namespace PluralKit.Bot.Commands {
|
||||
public class MiscCommands: ModuleBase<PKCommandContext> {
|
||||
[Command("invite")]
|
||||
[Remarks("invite")]
|
||||
|
@ -20,7 +20,7 @@ namespace PluralKit.Bot.Commands
|
||||
[Command]
|
||||
public async Task Query(PKSystem system = null) {
|
||||
if (system == null) system = Context.SenderSystem;
|
||||
if (system == null) throw Errors.NotOwnSystemError;
|
||||
if (system == null) throw Errors.NoSystemError;
|
||||
|
||||
await Context.Channel.SendMessageAsync(embed: await EmbedService.CreateSystemEmbed(system));
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ using Discord.WebSocket;
|
||||
|
||||
namespace PluralKit.Bot {
|
||||
public static class ContextUtils {
|
||||
public static async Task<bool> PromptYesNo(this ICommandContext ctx, IUserMessage message, TimeSpan? timeout = null) {
|
||||
public static async Task<bool> PromptYesNo(this ICommandContext ctx, IUserMessage message, IUser user = null, TimeSpan? timeout = null) {
|
||||
await message.AddReactionsAsync(new[] {new Emoji(Emojis.Success), new Emoji(Emojis.Error)});
|
||||
var reaction = await ctx.AwaitReaction(message, ctx.User, (r) => r.Emote.Name == Emojis.Success || r.Emote.Name == Emojis.Error, timeout ?? TimeSpan.FromMinutes(1));
|
||||
var reaction = await ctx.AwaitReaction(message, user ?? ctx.User, (r) => r.Emote.Name == Emojis.Success || r.Emote.Name == Emojis.Error, timeout ?? TimeSpan.FromMinutes(1));
|
||||
return reaction.Emote.Name == Emojis.Success;
|
||||
}
|
||||
|
||||
|
@ -28,5 +28,12 @@ namespace PluralKit.Bot {
|
||||
public static PKError AvatarNotAnImage(string mimeType) => new PKError($"The given link does not point to an image{(mimeType != null ? $" ({mimeType})" : "")}. Make sure you're using a direct link (ending in .jpg, .png, .gif).");
|
||||
public static PKError AvatarDimensionsTooLarge(int width, int height) => new PKError($"Image too large ({width}x{height} > {Limits.AvatarDimensionLimit}x{Limits.AvatarDimensionLimit}), try resizing the image.");
|
||||
public static PKError InvalidUrl(string url) => new PKError($"The given URL is invalid.");
|
||||
|
||||
public static PKError AccountAlreadyLinked => new PKError("That account is already linked to your system.");
|
||||
public static PKError AccountNotLinked => new PKError("That account isn't linked to your system.");
|
||||
public static PKError AccountInOtherSystem(PKSystem system) => new PKError($"The mentioned account is already linked to another system (see `pk;system {system.Hid}`).");
|
||||
public static PKError UnlinkingLastAccount => new PKError("Since this is the only account linked to this system, you cannot unlink it (as that would leave your system account-less).");
|
||||
public static PKError MemberLinkCancelled => new PKError("Member link cancelled.");
|
||||
public static PKError MemberUnlinkCancelled => new PKError("Member unlink cancelled.");
|
||||
}
|
||||
}
|
@ -66,7 +66,7 @@ namespace PluralKit.Bot
|
||||
public override async Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
var client = services.GetService<IDiscordClient>();
|
||||
var conn = services.GetService<IDbConnection>();
|
||||
var systems = services.GetService<SystemStore>();
|
||||
|
||||
// System references can take three forms:
|
||||
// - The direct user ID of an account connected to the system
|
||||
@ -74,20 +74,20 @@ namespace PluralKit.Bot
|
||||
// - A system hid
|
||||
|
||||
// First, try direct user ID parsing
|
||||
if (ulong.TryParse(input, out var idFromNumber)) return await FindSystemByAccountHelper(idFromNumber, client, conn);
|
||||
if (ulong.TryParse(input, out var idFromNumber)) return await FindSystemByAccountHelper(idFromNumber, client, systems);
|
||||
|
||||
// Then, try mention parsing.
|
||||
if (MentionUtils.TryParseUser(input, out var idFromMention)) return await FindSystemByAccountHelper(idFromMention, client, conn);
|
||||
if (MentionUtils.TryParseUser(input, out var idFromMention)) return await FindSystemByAccountHelper(idFromMention, client, systems);
|
||||
|
||||
// Finally, try HID parsing
|
||||
var res = await conn.QuerySingleOrDefaultAsync<PKSystem>("select * from systems where hid = @Hid", new { Hid = input });
|
||||
var res = await systems.GetByHid(input);
|
||||
if (res != null) return TypeReaderResult.FromSuccess(res);
|
||||
return TypeReaderResult.FromError(CommandError.ObjectNotFound, $"System with ID `{input}` not found.");
|
||||
}
|
||||
|
||||
async Task<TypeReaderResult> FindSystemByAccountHelper(ulong id, IDiscordClient client, IDbConnection conn)
|
||||
async Task<TypeReaderResult> FindSystemByAccountHelper(ulong id, IDiscordClient client, SystemStore systems)
|
||||
{
|
||||
var foundByAccountId = await conn.QuerySingleOrDefaultAsync<PKSystem>("select * from accounts, systems where accounts.system = system.id and accounts.id = @Id", new { Id = id });
|
||||
var foundByAccountId = await systems.GetByAccount(id);
|
||||
if (foundByAccountId != null) return TypeReaderResult.FromSuccess(foundByAccountId);
|
||||
|
||||
// We didn't find any, so we try to resolve the user ID to find the associated account,
|
||||
|
@ -23,9 +23,13 @@ namespace PluralKit {
|
||||
public async Task Link(PKSystem system, ulong accountId) {
|
||||
await conn.ExecuteAsync("insert into accounts (uid, system) values (@Id, @SystemId)", new { Id = accountId, SystemId = system.Id });
|
||||
}
|
||||
|
||||
public async Task Unlink(PKSystem system, ulong accountId) {
|
||||
await conn.ExecuteAsync("delete from accounts where uid = @Id and system = @SystemId", new { Id = accountId, SystemId = system.Id });
|
||||
}
|
||||
|
||||
public async Task<PKSystem> GetByAccount(ulong accountId) {
|
||||
return await conn.QuerySingleOrDefaultAsync<PKSystem>("select systems.* from systems, accounts where accounts.system = system.id and accounts.uid = @Id", new { Id = accountId });
|
||||
return await conn.QuerySingleOrDefaultAsync<PKSystem>("select systems.* from systems, accounts where accounts.system = systems.id and accounts.uid = @Id", new { Id = accountId });
|
||||
}
|
||||
|
||||
public async Task<PKSystem> GetByHid(string hid) {
|
||||
|
Loading…
Reference in New Issue
Block a user