Replace most "code-escaped" literals with properly-escaping helpers
This commit is contained in:
parent
6e88739424
commit
203dbc65a1
@ -35,7 +35,7 @@ namespace PluralKit.Bot
|
|||||||
else if (!ctx.HasNext())
|
else if (!ctx.HasNext())
|
||||||
await ctx.Reply(embed: await CreateAutoproxyStatusEmbed(ctx));
|
await ctx.Reply(embed: await CreateAutoproxyStatusEmbed(ctx));
|
||||||
else
|
else
|
||||||
throw new PKSyntaxError($"Invalid autoproxy mode `{ctx.PopArgument().EscapeMarkdown()}`.");
|
throw new PKSyntaxError($"Invalid autoproxy mode {ctx.PopArgument().AsCode()}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AutoproxyOff(Context ctx)
|
private async Task AutoproxyOff(Context ctx)
|
||||||
|
@ -190,7 +190,7 @@ namespace PluralKit.Bot
|
|||||||
return ctx.Execute<Member>(MemberRandom, m => m.MemberRandom(ctx));
|
return ctx.Execute<Member>(MemberRandom, m => m.MemberRandom(ctx));
|
||||||
|
|
||||||
ctx.Reply(
|
ctx.Reply(
|
||||||
$"{Emojis.Error} Unknown command `{ctx.PeekArgument()}`. For a list of possible commands, see <https://pluralkit.me/commands>.");
|
$"{Emojis.Error} Unknown command {ctx.PeekArgument().AsCode()}. For a list of possible commands, see <https://pluralkit.me/commands>.");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,7 +442,7 @@ namespace PluralKit.Bot
|
|||||||
return $"Account with ID `{id}` not found.";
|
return $"Account with ID `{id}` not found.";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"System with ID `{input}` not found.";
|
return $"System with ID {input.AsCode()} not found.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,10 +65,7 @@ namespace PluralKit.Bot
|
|||||||
if (target.ProxyTags.Count == 0)
|
if (target.ProxyTags.Count == 0)
|
||||||
await ctx.Reply("This member does not have any proxy tags.");
|
await ctx.Reply("This member does not have any proxy tags.");
|
||||||
else
|
else
|
||||||
{
|
await ctx.Reply($"This member's proxy tags are:\n{target.ProxyTagsString("\n")}");
|
||||||
var tags = string.Join("\n", target.ProxyTags.Select(t => $"``{t.ProxyString.EscapeBacktickPair()}``"));
|
|
||||||
await ctx.Reply($"This member's proxy tags are:\n{tags}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Subcommand: "add"
|
// Subcommand: "add"
|
||||||
else if (ctx.Match("add", "append"))
|
else if (ctx.Match("add", "append"))
|
||||||
@ -88,7 +85,7 @@ namespace PluralKit.Bot
|
|||||||
var patch = new MemberPatch {ProxyTags = Partial<ProxyTag[]>.Present(newTags.ToArray())};
|
var patch = new MemberPatch {ProxyTags = Partial<ProxyTag[]>.Present(newTags.ToArray())};
|
||||||
await _db.Execute(conn => conn.UpdateMember(target.Id, patch));
|
await _db.Execute(conn => conn.UpdateMember(target.Id, patch));
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} Added proxy tags ``{tagToAdd.ProxyString.EscapeBacktickPair()}``.");
|
await ctx.Reply($"{Emojis.Success} Added proxy tags {tagToAdd.ProxyString.AsCode()}.");
|
||||||
}
|
}
|
||||||
// Subcommand: "remove"
|
// Subcommand: "remove"
|
||||||
else if (ctx.Match("remove", "delete"))
|
else if (ctx.Match("remove", "delete"))
|
||||||
@ -105,7 +102,7 @@ namespace PluralKit.Bot
|
|||||||
var patch = new MemberPatch {ProxyTags = Partial<ProxyTag[]>.Present(newTags.ToArray())};
|
var patch = new MemberPatch {ProxyTags = Partial<ProxyTag[]>.Present(newTags.ToArray())};
|
||||||
await _db.Execute(conn => conn.UpdateMember(target.Id, patch));
|
await _db.Execute(conn => conn.UpdateMember(target.Id, patch));
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} Removed proxy tags ``{tagToRemove.ProxyString.EscapeBacktickPair()}``.");
|
await ctx.Reply($"{Emojis.Success} Removed proxy tags {tagToRemove.ProxyString.AsCode()}.");
|
||||||
}
|
}
|
||||||
// Subcommand: bare proxy tag given
|
// Subcommand: bare proxy tag given
|
||||||
else
|
else
|
||||||
@ -129,7 +126,7 @@ namespace PluralKit.Bot
|
|||||||
var patch = new MemberPatch {ProxyTags = Partial<ProxyTag[]>.Present(newTags)};
|
var patch = new MemberPatch {ProxyTags = Partial<ProxyTag[]>.Present(newTags)};
|
||||||
await _db.Execute(conn => conn.UpdateMember(target.Id, patch));
|
await _db.Execute(conn => conn.UpdateMember(target.Id, patch));
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} Member proxy tags set to ``{requestedTag.ProxyString.EscapeBacktickPair()}``.");
|
await ctx.Reply($"{Emojis.Success} Member proxy tags set to {requestedTag.ProxyString.AsCode()}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ namespace PluralKit.Bot {
|
|||||||
{
|
{
|
||||||
var guildIdStr = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a server ID or run this command in a server.");
|
var guildIdStr = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a server ID or run this command in a server.");
|
||||||
if (!ulong.TryParse(guildIdStr, out var guildId))
|
if (!ulong.TryParse(guildIdStr, out var guildId))
|
||||||
throw new PKSyntaxError($"Could not parse `{guildIdStr}` as an ID.");
|
throw new PKSyntaxError($"Could not parse {guildIdStr.AsCode()} as an ID.");
|
||||||
|
|
||||||
guild = ctx.Client.GetGuild(guildId);
|
guild = ctx.Client.GetGuild(guildId);
|
||||||
if (guild != null) senderGuildUser = await guild.GetMember(ctx.Author.Id);
|
if (guild != null) senderGuildUser = await guild.GetMember(ctx.Author.Id);
|
||||||
@ -196,7 +196,7 @@ namespace PluralKit.Bot {
|
|||||||
messageId = id;
|
messageId = id;
|
||||||
else if (Regex.Match(word, "https://discord(?:app)?.com/channels/\\d+/\\d+/(\\d+)") is Match match && match.Success)
|
else if (Regex.Match(word, "https://discord(?:app)?.com/channels/\\d+/\\d+/(\\d+)") is Match match && match.Success)
|
||||||
messageId = ulong.Parse(match.Groups[1].Value);
|
messageId = ulong.Parse(match.Groups[1].Value);
|
||||||
else throw new PKSyntaxError($"Could not parse `{word}` as a message ID or link.");
|
else throw new PKSyntaxError($"Could not parse {word.AsCode()} as a message ID or link.");
|
||||||
|
|
||||||
var message = await _data.GetMessage(messageId);
|
var message = await _data.GetMessage(messageId);
|
||||||
if (message == null) throw Errors.MessageNotFound(messageId);
|
if (message == null) throw Errors.MessageNotFound(messageId);
|
||||||
|
@ -15,13 +15,13 @@ namespace PluralKit.Bot
|
|||||||
if (!ctx.HasNext())
|
if (!ctx.HasNext())
|
||||||
throw new PKSyntaxError("You must pass a privacy level (`public` or `private`)");
|
throw new PKSyntaxError("You must pass a privacy level (`public` or `private`)");
|
||||||
|
|
||||||
throw new PKSyntaxError($"Invalid privacy level `{ctx.PopArgument()}` (must be `public` or `private`).");
|
throw new PKSyntaxError($"Invalid privacy level {ctx.PopArgument().AsCode()} (must be `public` or `private`).");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SystemPrivacySubject PopSystemPrivacySubject(this Context ctx)
|
public static SystemPrivacySubject PopSystemPrivacySubject(this Context ctx)
|
||||||
{
|
{
|
||||||
if (!SystemPrivacyUtils.TryParseSystemPrivacy(ctx.PeekArgument(), out var subject))
|
if (!SystemPrivacyUtils.TryParseSystemPrivacy(ctx.PeekArgument(), out var subject))
|
||||||
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument()}` (must be `description`, `members`, `front`, `fronthistory`, or `all`).");
|
throw new PKSyntaxError($"Invalid privacy subject {ctx.PopArgument().AsCode()} (must be `description`, `members`, `front`, `fronthistory`, or `all`).");
|
||||||
|
|
||||||
ctx.PopArgument();
|
ctx.PopArgument();
|
||||||
return subject;
|
return subject;
|
||||||
@ -30,7 +30,7 @@ namespace PluralKit.Bot
|
|||||||
public static MemberPrivacySubject PopMemberPrivacySubject(this Context ctx)
|
public static MemberPrivacySubject PopMemberPrivacySubject(this Context ctx)
|
||||||
{
|
{
|
||||||
if (!MemberPrivacyUtils.TryParseMemberPrivacy(ctx.PeekArgument(), out var subject))
|
if (!MemberPrivacyUtils.TryParseMemberPrivacy(ctx.PeekArgument(), out var subject))
|
||||||
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument()}` (must be `name`, `description`, `avatar`, `birthday`, `pronouns`, `metadata`, `visibility`, or `all).");
|
throw new PKSyntaxError($"Invalid privacy subject {ctx.PopArgument().AsCode()} (must be `name`, `description`, `avatar`, `birthday`, `pronouns`, `metadata`, `visibility`, or `all).");
|
||||||
|
|
||||||
ctx.PopArgument();
|
ctx.PopArgument();
|
||||||
return subject;
|
return subject;
|
||||||
@ -39,7 +39,7 @@ namespace PluralKit.Bot
|
|||||||
public static GroupPrivacySubject PopGroupPrivacySubject(this Context ctx)
|
public static GroupPrivacySubject PopGroupPrivacySubject(this Context ctx)
|
||||||
{
|
{
|
||||||
if (!GroupPrivacyUtils.TryParseGroupPrivacy(ctx.PeekArgument(), out var subject))
|
if (!GroupPrivacyUtils.TryParseGroupPrivacy(ctx.PeekArgument(), out var subject))
|
||||||
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument()}` (must be `description`, `icon`, `visibility`, or `all).");
|
throw new PKSyntaxError($"Invalid privacy subject {ctx.PopArgument().AsCode()} (must be `description`, `icon`, `visibility`, or `all).");
|
||||||
|
|
||||||
ctx.PopArgument();
|
ctx.PopArgument();
|
||||||
return subject;
|
return subject;
|
||||||
|
@ -114,7 +114,7 @@ namespace PluralKit.Bot
|
|||||||
if (ctx.System.Tag == null)
|
if (ctx.System.Tag == null)
|
||||||
await ctx.Reply($"You currently have no system tag. To set one, type `pk;s tag <tag>`.");
|
await ctx.Reply($"You currently have no system tag. To set one, type `pk;s tag <tag>`.");
|
||||||
else
|
else
|
||||||
await ctx.Reply($"Your current system tag is `{ctx.System.Tag}`. To change it, type `pk;s tag <tag>`. To clear it, type `pk;s tag -clear`.");
|
await ctx.Reply($"Your current system tag is {ctx.System.Tag.AsCode()}. To change it, type `pk;s tag <tag>`. To clear it, type `pk;s tag -clear`.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ namespace PluralKit.Bot
|
|||||||
var patch = new SystemPatch {Tag = newTag};
|
var patch = new SystemPatch {Tag = newTag};
|
||||||
await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, patch));
|
await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, patch));
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} System tag changed. Member names will now end with `{newTag}` when proxied.");
|
await ctx.Reply($"{Emojis.Success} System tag changed. Member names will now end with {newTag.AsCode()} when proxied.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,20 +96,20 @@ namespace PluralKit.Bot {
|
|||||||
public static PKError ImportCancelled => new PKError("Import cancelled.");
|
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?");
|
public static PKError MessageNotFound(ulong id) => new PKError($"Message with ID '{id}' not found. Are you sure it's a message proxied by PluralKit?");
|
||||||
|
|
||||||
public static PKError DurationParseError(string durationStr) => new PKError($"Could not parse '{durationStr}' as a valid duration. Try a format such as `30d`, `1d3h` or `20m30s`.");
|
public static PKError DurationParseError(string durationStr) => new PKError($"Could not parse {durationStr.AsCode()} as a valid duration. Try a format such as `30d`, `1d3h` or `20m30s`.");
|
||||||
public static PKError FrontPercentTimeInFuture => new PKError("Cannot get the front percent between now and a time in the future.");
|
public static PKError FrontPercentTimeInFuture => new PKError("Cannot get the front percent between now and a time in the future.");
|
||||||
|
|
||||||
public static PKError GuildNotFound(ulong guildId) => new PKError($"Guild with ID {guildId} not found. Note that you must be a member of the guild you are querying.");
|
public static PKError GuildNotFound(ulong guildId) => new PKError($"Guild with ID {guildId} not found. Note that you must be a member of the guild you are querying.");
|
||||||
|
|
||||||
public static PKError DisplayNameTooLong(string displayName, int maxLength) => new PKError(
|
public static PKError DisplayNameTooLong(string displayName, int maxLength) => new PKError(
|
||||||
$"Display name too long ({displayName.Length} > {maxLength} characters). Use a shorter display name, or shorten your system tag.");
|
$"Display name too long ({displayName.Length} > {maxLength} characters). Use a shorter display name, or shorten your system tag.");
|
||||||
public static PKError ProxyNameTooShort(string name) => new PKError($"The webhook's name, `{name}`, is shorter than two characters, and thus cannot be proxied. Please change the member name or use a longer system tag.");
|
public static PKError ProxyNameTooShort(string name) => new PKError($"The webhook's name, {name.AsCode()}, is shorter than two characters, and thus cannot be proxied. Please change the member name or use a longer system tag.");
|
||||||
public static PKError ProxyNameTooLong(string name) => new PKError($"The webhook's name, {name}, is too long ({name.Length} > {Limits.MaxProxyNameLength} characters), and thus cannot be proxied. Please change the member name, display name or server display name, or use a shorter system tag.");
|
public static PKError ProxyNameTooLong(string name) => new PKError($"The webhook's name, {name.AsCode()}, is too long ({name.Length} > {Limits.MaxProxyNameLength} characters), and thus cannot be proxied. Please change the member name, display name or server display name, or use a shorter system tag.");
|
||||||
|
|
||||||
public static PKError ProxyTagAlreadyExists(ProxyTag tagToAdd, PKMember member) => new PKError($"That member already has the proxy tag `` {tagToAdd.ProxyString.EscapeBacktickPair()} ``. The member currently has these tags: {member.ProxyTagsString()}");
|
public static PKError ProxyTagAlreadyExists(ProxyTag tagToAdd, PKMember member) => new PKError($"That member already has the proxy tag {tagToAdd.ProxyString.AsCode()}. The member currently has these tags: {member.ProxyTagsString()}");
|
||||||
public static PKError ProxyTagDoesNotExist(ProxyTag tagToRemove, PKMember member) => new PKError($"That member does not have the proxy tag ``{tagToRemove.ProxyString.EscapeBacktickPair()}``. The member currently has these tags: {member.ProxyTagsString()}");
|
public static PKError ProxyTagDoesNotExist(ProxyTag tagToRemove, PKMember member) => new PKError($"That member does not have the proxy tag {tagToRemove.ProxyString.AsCode()}. The member currently has these tags: {member.ProxyTagsString()}");
|
||||||
public static PKError LegacyAlreadyHasProxyTag(ProxyTag requested, PKMember member) => new PKError($"This member already has more than one proxy tag set: {member.ProxyTagsString()}\nConsider using the ``pk;member {member.Hid} proxy add {requested.ProxyString.EscapeBacktickPair()}`` command instead.");
|
public static PKError LegacyAlreadyHasProxyTag(ProxyTag requested, PKMember member) => new PKError($"This member already has more than one proxy tag set: {member.ProxyTagsString()}\nConsider using the {$"pk;member {member.Reference()} proxy add {requested.ProxyString}".AsCode()} command instead.");
|
||||||
public static PKError EmptyProxyTags(PKMember member) => new PKError($"The example proxy `text` is equivalent to having no proxy tags at all, since there are no symbols or brackets on either end. If you'd like to clear your proxy tags, use `pk;member {member.Hid} proxy clear`.");
|
public static PKError EmptyProxyTags(PKMember member) => new PKError($"The example proxy `text` is equivalent to having no proxy tags at all, since there are no symbols or brackets on either end. If you'd like to clear your proxy tags, use `pk;member {member.Reference()} proxy clear`.");
|
||||||
|
|
||||||
public static PKError GenericCancelled() => new PKError("Operation cancelled.");
|
public static PKError GenericCancelled() => new PKError("Operation cancelled.");
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ namespace PluralKit.Bot
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await guildUser.SendMessageFixedAsync($"{Emojis.Error} {msg.Member.DisplayName()}'s system has disabled reaction pings. If you want to mention them anyway, you can copy/paste the following message:");
|
await guildUser.SendMessageFixedAsync($"{Emojis.Error} {msg.Member.DisplayName()}'s system has disabled reaction pings. If you want to mention them anyway, you can copy/paste the following message:");
|
||||||
await guildUser.SendMessageFixedAsync($"`<@{msg.Message.Sender}>`");
|
await guildUser.SendMessageFixedAsync($"<@{msg.Message.Sender}>".AsCode());
|
||||||
}
|
}
|
||||||
catch (UnauthorizedException) { }
|
catch (UnauthorizedException) { }
|
||||||
}
|
}
|
||||||
|
@ -111,8 +111,6 @@ namespace PluralKit.Bot {
|
|||||||
|
|
||||||
var groups = (await conn.QueryMemberGroups(member.Id)).Where(g => g.Visibility.CanAccess(ctx)).ToList();
|
var groups = (await conn.QueryMemberGroups(member.Id)).Where(g => g.Visibility.CanAccess(ctx)).ToList();
|
||||||
|
|
||||||
var proxyTagsStr = string.Join('\n', member.ProxyTags.Select(t => $"`` {t.ProxyString} ``"));
|
|
||||||
|
|
||||||
var eb = new DiscordEmbedBuilder()
|
var eb = new DiscordEmbedBuilder()
|
||||||
// TODO: add URL of website when that's up
|
// TODO: add URL of website when that's up
|
||||||
.WithAuthor(name, iconUrl: DiscordUtils.WorkaroundForUrlBug(avatar))
|
.WithAuthor(name, iconUrl: DiscordUtils.WorkaroundForUrlBug(avatar))
|
||||||
@ -136,7 +134,7 @@ namespace PluralKit.Bot {
|
|||||||
if (member.BirthdayFor(ctx) != null) eb.AddField("Birthdate", member.BirthdayString, true);
|
if (member.BirthdayFor(ctx) != null) eb.AddField("Birthdate", member.BirthdayString, true);
|
||||||
if (member.PronounsFor(ctx) is {} pronouns && !string.IsNullOrWhiteSpace(pronouns)) eb.AddField("Pronouns", pronouns.Truncate(1024), true);
|
if (member.PronounsFor(ctx) is {} pronouns && !string.IsNullOrWhiteSpace(pronouns)) eb.AddField("Pronouns", pronouns.Truncate(1024), true);
|
||||||
if (member.MessageCountFor(ctx) is {} count && count > 0) eb.AddField("Message Count", member.MessageCount.ToString(), true);
|
if (member.MessageCountFor(ctx) is {} count && count > 0) eb.AddField("Message Count", member.MessageCount.ToString(), true);
|
||||||
if (member.HasProxyTags) eb.AddField("Proxy Tags", string.Join('\n', proxyTagsStr).Truncate(1024), true);
|
if (member.HasProxyTags) eb.AddField("Proxy Tags", member.ProxyTagsString("\n").Truncate(1024), true);
|
||||||
// --- For when this gets added to the member object itself or however they get added
|
// --- For when this gets added to the member object itself or however they get added
|
||||||
// if (member.LastMessage != null && member.MetadataPrivacy.CanAccess(ctx)) eb.AddField("Last message:" FormatTimestamp(DiscordUtils.SnowflakeToInstant(m.LastMessage.Value)));
|
// if (member.LastMessage != null && member.MetadataPrivacy.CanAccess(ctx)) eb.AddField("Last message:" FormatTimestamp(DiscordUtils.SnowflakeToInstant(m.LastMessage.Value)));
|
||||||
// if (member.LastSwitchTime != null && m.MetadataPrivacy.CanAccess(ctx)) eb.AddField("Last switched in:", FormatTimestamp(member.LastSwitchTime.Value));
|
// if (member.LastSwitchTime != null && m.MetadataPrivacy.CanAccess(ctx)) eb.AddField("Last switched in:", FormatTimestamp(member.LastSwitchTime.Value));
|
||||||
|
@ -209,11 +209,29 @@ namespace PluralKit.Bot
|
|||||||
else return input;
|
else return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string EscapeBacktickPair(this string input){
|
public static string EscapeBacktickPair(this string input)
|
||||||
Regex doubleBacktick = new Regex(@"``", RegexOptions.Multiline);
|
{
|
||||||
//Run twice to catch any pairs that are created from the first pass, pairs shouldn't be created in the second as they are created from odd numbers of backticks, even numbers are all caught on the first pass
|
if (input == null)
|
||||||
if(input != null) return doubleBacktick.Replace(doubleBacktick.Replace(input, "`\ufeff`"),"`\ufeff`");
|
return null;
|
||||||
else return input;
|
|
||||||
|
// Break all pairs of backticks by placing a ZWNBSP (U+FEFF) between them.
|
||||||
|
// Run twice to catch any pairs that are created from the first pass
|
||||||
|
var escaped = input
|
||||||
|
.Replace("``", "`\ufeff`")
|
||||||
|
.Replace("``", "`\ufeff`");
|
||||||
|
|
||||||
|
// Escape the start/end of the string if necessary to better "connect" with other things
|
||||||
|
if (escaped.StartsWith("`")) escaped = "\ufeff" + escaped;
|
||||||
|
if (escaped.EndsWith("`")) escaped = escaped + "\ufeff";
|
||||||
|
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string AsCode(this string input)
|
||||||
|
{
|
||||||
|
// Inline code blocks started with two backticks need to end with two backticks
|
||||||
|
// So, surrounding with two backticks, then escaping all backtick pairs makes it impossible(!) to "break out"
|
||||||
|
return $"``{EscapeBacktickPair(input)}``";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task<DiscordUser> GetUser(this DiscordRestClient client, ulong id) =>
|
public static Task<DiscordUser> GetUser(this DiscordRestClient client, ulong id) =>
|
||||||
|
@ -14,7 +14,8 @@ using PluralKit.Core;
|
|||||||
namespace PluralKit.Bot
|
namespace PluralKit.Bot
|
||||||
{
|
{
|
||||||
public static class MiscUtils {
|
public static class MiscUtils {
|
||||||
public static string ProxyTagsString(this PKMember member) => string.Join(", ", member.ProxyTags.Select(t => $"``{t.ProxyString.EscapeBacktickPair()}``"));
|
public static string ProxyTagsString(this PKMember member, string separator = ", ") =>
|
||||||
|
string.Join(separator, member.ProxyTags.Select(t => t.ProxyString.AsCode()));
|
||||||
|
|
||||||
public static bool IsOurProblem(this Exception e)
|
public static bool IsOurProblem(this Exception e)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user