feat: implement system avatar commands

This commit is contained in:
dusk 2025-04-04 03:50:07 +09:00
parent 293570c91c
commit b62340cbb3
No known key found for this signature in database
11 changed files with 155 additions and 101 deletions

View file

@ -6,34 +6,8 @@ namespace PluralKit.Bot;
public static class ContextAvatarExt
{
public static async Task<ParsedImage?> MatchImage(this Context ctx)
public static ParsedImage? ExtractImageFromAttachment(this Context ctx)
{
// If we have a user @mention/ID, use their avatar
if (await ctx.MatchUser() is { } user)
{
var url = user.AvatarUrl("png", 256);
return new ParsedImage { Url = url, Source = AvatarSource.User, SourceUser = user };
}
// If we have raw or plaintext, don't try to parse as a URL
if (ctx.PeekMatchFormat() != ReplyFormat.Standard)
return null;
// If we have a positional argument, try to parse it as a URL
var arg = ctx.RemainderOrNull();
if (arg != null)
{
// Allow surrounding the URL with <angle brackets> to "de-embed"
if (arg.StartsWith("<") && arg.EndsWith(">"))
arg = arg.Substring(1, arg.Length - 2);
if (!Core.MiscUtils.TryMatchUri(arg, out var uri))
throw Errors.InvalidUrl;
// ToString URL-decodes, which breaks URLs to spaces; AbsoluteUri doesn't
return new ParsedImage { Url = uri.AbsoluteUri, Source = AvatarSource.Url };
}
// If we have an attachment, use that
if (ctx.Message.Attachments.FirstOrDefault() is { } attachment)
{
@ -51,6 +25,33 @@ public static class ContextAvatarExt
// and if there are no attachments (which would have been caught just before)
return null;
}
public static async Task<ParsedImage?> GetUserPfp(this Context ctx, string arg)
{
// If we have a user @mention/ID, use their avatar
if (await ctx.ParseUser(arg) is { } user)
{
var url = user.AvatarUrl("png", 256);
return new ParsedImage { Url = url, Source = AvatarSource.User, SourceUser = user };
}
return null;
}
public static ParsedImage ParseImage(this Context ctx, string arg)
{
// Allow surrounding the URL with <angle brackets> to "de-embed"
if (arg.StartsWith("<") && arg.EndsWith(">"))
arg = arg.Substring(1, arg.Length - 2);
if (!Core.MiscUtils.TryMatchUri(arg, out var uri))
throw Errors.InvalidUrl;
// ToString URL-decodes, which breaks URLs to spaces; AbsoluteUri doesn't
return new ParsedImage { Url = uri.AbsoluteUri, Source = AvatarSource.Url };
}
public static async Task<ParsedImage?> MatchImage(this Context ctx)
{
throw new NotImplementedException();
}
}
public struct ParsedImage