run dotnet format

This commit is contained in:
spiral
2021-08-27 11:03:47 -04:00
parent 05989242f9
commit ac2671452d
278 changed files with 1913 additions and 1808 deletions

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
@@ -8,11 +8,13 @@ using PluralKit.Core;
using SixLabors.ImageSharp;
namespace PluralKit.Bot {
public static class AvatarUtils {
namespace PluralKit.Bot
{
public static class AvatarUtils
{
public static async Task VerifyAvatarOrThrow(HttpClient client, string url, bool isFullSizeImage = false)
{
if (url.Length > Limits.MaxUriLength)
if (url.Length > Limits.MaxUriLength)
throw Errors.UrlTooLong(url);
// List of MIME types we consider acceptable

View File

@@ -17,8 +17,10 @@ using NodaTime;
using PluralKit.Bot.Interactive;
using PluralKit.Core;
namespace PluralKit.Bot {
public static class ContextUtils {
namespace PluralKit.Bot
{
public static class ContextUtils
{
public static async Task<bool> ConfirmClear(this Context ctx, string toClear)
{
if (!(await ctx.PromptYesNo($"{Emojis.Warn} Are you sure you want to clear {toClear}?", "Clear"))) throw Errors.GenericCancelled();
@@ -50,7 +52,7 @@ namespace PluralKit.Bot {
if (predicate != null && !predicate.Invoke(evt)) return false; // Check predicate
return true;
}
return await ctx.Services.Resolve<HandlerQueue<MessageReactionAddEvent>>().WaitFor(ReactionPredicate, timeout);
}
@@ -58,20 +60,21 @@ namespace PluralKit.Bot {
{
bool Predicate(MessageCreateEvent e) =>
e.Author.Id == ctx.Author.Id && e.ChannelId == ctx.Channel.Id;
var msg = await ctx.Services.Resolve<HandlerQueue<MessageCreateEvent>>()
.WaitFor(Predicate, Duration.FromMinutes(1));
return string.Equals(msg.Content, expectedReply, StringComparison.InvariantCultureIgnoreCase);
}
public static async Task Paginate<T>(this Context ctx, IAsyncEnumerable<T> items, int totalCount, int itemsPerPage, string title, string color, Func<EmbedBuilder, IEnumerable<T>, Task> renderer) {
public static async Task Paginate<T>(this Context ctx, IAsyncEnumerable<T> items, int totalCount, int itemsPerPage, string title, string color, Func<EmbedBuilder, IEnumerable<T>, Task> renderer)
{
// TODO: make this generic enough we can use it in Choose<T> below
var buffer = new List<T>();
await using var enumerator = items.GetAsyncEnumerator();
var pageCount = (int) Math.Ceiling(totalCount / (double) itemsPerPage);
var pageCount = (int)Math.Ceiling(totalCount / (double)itemsPerPage);
async Task<Embed> MakeEmbedForPage(int page)
{
var bufferedItemsNeeded = (page + 1) * itemsPerPage;
@@ -79,10 +82,10 @@ namespace PluralKit.Bot {
buffer.Add(enumerator.Current);
var eb = new EmbedBuilder();
eb.Title(pageCount > 1 ? $"[{page+1}/{pageCount}] {title}" : title);
eb.Title(pageCount > 1 ? $"[{page + 1}/{pageCount}] {title}" : title);
if (color != null)
eb.Color(color.ToDiscordColor());
await renderer(eb, buffer.Skip(page*itemsPerPage).Take(itemsPerPage));
await renderer(eb, buffer.Skip(page * itemsPerPage).Take(itemsPerPage));
return eb.Build();
}
@@ -94,9 +97,11 @@ namespace PluralKit.Bot {
var _ = ctx.Rest.CreateReactionsBulk(msg, botEmojis); // Again, "fork"
try {
try
{
var currentPage = 0;
while (true) {
while (true)
{
var reaction = await ctx.AwaitReaction(msg, ctx.Author, timeout: Duration.FromMinutes(5));
// Increment/decrement page counter based on which reaction was clicked
@@ -105,19 +110,21 @@ namespace PluralKit.Bot {
if (reaction.Emoji.Name == "\u27A1") currentPage = (currentPage + 1) % pageCount; // >
if (reaction.Emoji.Name == "\u23E9") currentPage = pageCount - 1; // >>
if (reaction.Emoji.Name == Emojis.Error) break; // X
// C#'s % operator is dumb and wrong, so we fix negative numbers
if (currentPage < 0) currentPage += pageCount;
// If we can, remove the user's reaction (so they can press again quickly)
if (ctx.BotPermissions.HasFlag(PermissionSet.ManageMessages))
await ctx.Rest.DeleteUserReaction(msg.ChannelId, msg.Id, reaction.Emoji, reaction.UserId);
// Edit the embed with the new page
var embed = await MakeEmbedForPage(currentPage);
await ctx.Rest.EditMessage(msg.ChannelId, msg.Id, new MessageEditRequest {Embed = embed});
await ctx.Rest.EditMessage(msg.ChannelId, msg.Id, new MessageEditRequest { Embed = embed });
}
} catch (TimeoutException) {
}
catch (TimeoutException)
{
// "escape hatch", clean up as if we hit X
}
@@ -132,7 +139,7 @@ namespace PluralKit.Bot {
// either way, nothing to do here
catch (ForbiddenException) { }
}
public static async Task<T> Choose<T>(this Context ctx, string description, IList<T> items, Func<T, string> display = null)
{
// Generate a list of :regional_indicator_?: emoji surrogate pairs (starting at codepoint 0x1F1E6)
@@ -157,27 +164,27 @@ namespace PluralKit.Bot {
if (items.Count > pageSize)
{
var currPage = 0;
var pageCount = (items.Count-1) / pageSize + 1;
var pageCount = (items.Count - 1) / pageSize + 1;
// Send the original message
var msg = await ctx.Reply($"**[Page {currPage + 1}/{pageCount}]**\n{description}\n{MakeOptionList(currPage)}");
// Add back/forward reactions and the actual indicator emojis
async Task AddEmojis()
{
await ctx.Rest.CreateReaction(msg.ChannelId, msg.Id, new() { Name = "\u2B05" });
await ctx.Rest.CreateReaction(msg.ChannelId, msg.Id, new() { Name = "\u27A1" });
for (int i = 0; i < items.Count; i++)
for (int i = 0; i < items.Count; i++)
await ctx.Rest.CreateReaction(msg.ChannelId, msg.Id, new() { Name = indicators[i] });
}
var _ = AddEmojis(); // Not concerned about awaiting
while (true)
{
// Wait for a reaction
var reaction = await ctx.AwaitReaction(msg, ctx.Author);
// If it's a movement reaction, inc/dec the page index
if (reaction.Emoji.Name == "\u2B05") currPage -= 1; // <
if (reaction.Emoji.Name == "\u27A1") currPage += 1; // >
@@ -210,17 +217,17 @@ namespace PluralKit.Bot {
async Task AddEmojis()
{
for (int i = 0; i < items.Count; i++)
await ctx.Rest.CreateReaction(msg.ChannelId, msg.Id, new() {Name = indicators[i]});
await ctx.Rest.CreateReaction(msg.ChannelId, msg.Id, new() { Name = indicators[i] });
}
var _ = AddEmojis();
// Then wait for a reaction and return whichever one we found
var reaction = await ctx.AwaitReaction(msg, ctx.Author,rx => indicators.Contains(rx.Emoji.Name));
var reaction = await ctx.AwaitReaction(msg, ctx.Author, rx => indicators.Contains(rx.Emoji.Name));
return items[Array.IndexOf(indicators, reaction.Emoji.Name)];
}
}
public static async Task BusyIndicator(this Context ctx, Func<Task> f, string emoji = "\u23f3" /* hourglass */)
{
await ctx.BusyIndicator<object>(async () =>
@@ -239,13 +246,13 @@ namespace PluralKit.Bot {
try
{
await Task.WhenAll(ctx.Rest.CreateReaction(ctx.Message.ChannelId, ctx.Message.Id, new() {Name = emoji}), task);
await Task.WhenAll(ctx.Rest.CreateReaction(ctx.Message.ChannelId, ctx.Message.Id, new() { Name = emoji }), task);
return await task;
}
finally
{
var _ = ctx.Rest.DeleteOwnReaction(ctx.Message.ChannelId, ctx.Message.Id, new() { Name = emoji });
}
}
}
}
}

View File

@@ -24,7 +24,7 @@ namespace PluralKit.Bot
public const uint Green = 0x00cc78;
public const uint Red = 0xef4b3d;
public const uint Gray = 0x979c9f;
private static readonly Regex USER_MENTION = new Regex("<@!?(\\d{17,19})>");
private static readonly Regex ROLE_MENTION = new Regex("<@&(\\d{17,19})>");
private static readonly Regex EVERYONE_HERE_MENTION = new Regex("@(everyone|here)");
@@ -36,23 +36,23 @@ namespace PluralKit.Bot
// corresponding to: https://github.com/Khan/simple-markdown/blob/master/src/index.js#L1489
// I added <? and >? at the start/end; they need to be handled specially later...
private static readonly Regex UNBROKEN_LINK_REGEX = new Regex("<?(https?:\\/\\/[^\\s<]+[^<.,:;\"')\\]\\s])>?");
public static string NameAndMention(this User user)
{
return $"{user.Username}#{user.Discriminator} ({user.Mention()})";
}
public static Instant SnowflakeToInstant(ulong snowflake) =>
Instant.FromUtc(2015, 1, 1, 0, 0, 0) + Duration.FromMilliseconds(snowflake >> 22);
public static ulong InstantToSnowflake(Instant time) =>
(ulong) (time - Instant.FromUtc(2015, 1, 1, 0, 0, 0)).TotalMilliseconds << 22;
(ulong)(time - Instant.FromUtc(2015, 1, 1, 0, 0, 0)).TotalMilliseconds << 22;
public static async Task CreateReactionsBulk(this DiscordApiClient rest, Message msg, string[] reactions)
{
foreach (var reaction in reactions)
{
await rest.CreateReaction(msg.ChannelId, msg.Id, new() {Name = reaction});
await rest.CreateReaction(msg.ChannelId, msg.Id, new() { Name = reaction });
}
}
@@ -97,22 +97,23 @@ namespace PluralKit.Bot
var users = USER_MENTION.Matches(input).Select(x => ulong.Parse(x.Groups[1].Value));
var roles = ROLE_MENTION.Matches(input).Select(x => ulong.Parse(x.Groups[1].Value));
var everyone = EVERYONE_HERE_MENTION.IsMatch(input);
return new AllowedMentions
{
Users = users.Distinct().ToArray(),
Roles = roles.Distinct().ToArray(),
Parse = everyone ? new[] {AllowedMentions.ParseType.Everyone} : null
Parse = everyone ? new[] { AllowedMentions.ParseType.Everyone } : null
};
}
public static AllowedMentions RemoveUnmentionableRoles(this AllowedMentions mentions, Guild guild)
{
return mentions with {
return mentions with
{
Roles = mentions.Roles
?.Where(id => guild.Roles.FirstOrDefault(r => r.Id == id)?.Mentionable == true)
.ToArray()
};
};
}
public static string EscapeMarkdown(this string input)
@@ -146,7 +147,7 @@ namespace PluralKit.Bot
// So, surrounding with two backticks, then escaping all backtick pairs makes it impossible(!) to "break out"
return $"``{EscapeBacktickPair(input)}``";
}
public static EmbedBuilder WithSimpleLineContent(this EmbedBuilder eb, IEnumerable<string> lines)
{
static int CharacterLimit(int pageNumber) =>
@@ -178,7 +179,7 @@ namespace PluralKit.Bot
return $"<{match.Value}>";
});
public static string EventType(this IGatewayEvent evt) =>
public static string EventType(this IGatewayEvent evt) =>
evt.GetType().Name.Replace("Event", "");
public static bool HasReactionPermissions(Context ctx)
@@ -188,11 +189,11 @@ namespace PluralKit.Bot
}
public static bool IsValidGuildChannel(Channel channel) =>
channel.Type is
channel.Type is
Channel.ChannelType.GuildText or
Channel.ChannelType.GuildNews or
Channel.ChannelType.GuildNews or
Channel.ChannelType.GuildPublicThread or
Channel.ChannelType.GuildPrivateThread or
Channel.ChannelType.GuildNewsThread;
}
}
}

View File

@@ -13,7 +13,7 @@ namespace PluralKit.Bot
{
private readonly InteractionCreateEvent _evt;
private readonly ILifetimeScope _services;
public InteractionContext(InteractionCreateEvent evt, ILifetimeScope services)
{
_evt = evt;
@@ -55,9 +55,9 @@ namespace PluralKit.Bot
}
public async Task Respond(InteractionResponse.ResponseType type, InteractionApplicationCommandCallbackData? data)
{
{
var rest = _services.Resolve<DiscordApiClient>();
await rest.CreateInteractionResponse(_evt.Id, _evt.Token, new InteractionResponse {Type = type, Data = data});
await rest.CreateInteractionResponse(_evt.Id, _evt.Token, new InteractionResponse { Type = type, Data = data });
}
}
}

View File

@@ -5,7 +5,7 @@ namespace PluralKit.Bot.Utils
{
// PK note: class is wholesale copied from Discord.NET (MIT-licensed)
// https://github.com/discord-net/Discord.Net/blob/ff0fea98a65d907fbce07856f1a9ef4aebb9108b/src/Discord.Net.Core/Utils/MentionUtils.cs
/// <summary>
/// Provides a series of helper methods for parsing mentions.
/// </summary>

View File

@@ -16,10 +16,11 @@ using Polly.Timeout;
namespace PluralKit.Bot
{
public static class MiscUtils {
public static string ProxyTagsString(this PKMember member, string separator = ", ") =>
public static class MiscUtils
{
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)
{
// This function filters out sporadic errors out of our control from being reported to Sentry
@@ -40,24 +41,24 @@ namespace PluralKit.Bot
if (e is TimeoutRejectedException) return false;
// 5xxs? also not our problem :^)
if (e is UnknownDiscordRequestException udre && (int) udre.StatusCode >= 500) return false;
if (e is UnknownDiscordRequestException udre && (int)udre.StatusCode >= 500) return false;
// Webhook server errors are also *not our problem*
// (this includes rate limit errors, WebhookRateLimited is a subclass)
if (e is WebhookExecutionErrorOnDiscordsEnd) return false;
// Socket errors are *not our problem*
if (e.GetBaseException() is SocketException) return false;
// Tasks being cancelled for whatver reason are, you guessed it, also not our problem.
if (e is TaskCanceledException) return false;
// Sometimes Discord just times everything out.
if (e is TimeoutException) return false;
// Ignore "Database is shutting down" error
if (e is PostgresException pe && pe.SqlState == "57P03") return false;
// Ignore thread pool exhaustion errors
if (e is NpgsqlException npe && npe.Message.Contains("The connection pool has been exhausted")) return false;

View File

@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using System.Text.RegularExpressions;
using PluralKit.Core;
@@ -24,21 +24,21 @@ namespace PluralKit.Bot
bool IsSimple(string s) =>
// No spaces, no symbols, allow single quote but not at the start
Regex.IsMatch(s, "^[\\w\\d\\-_'?]+$") && !s.StartsWith("'");
// If it's very long (>25 chars), always use hid
if (name.Length >= 25)
return hid;
// If name is "simple" just use that
if (IsSimple(name))
if (IsSimple(name))
return name;
// If three or fewer "words" and they're all simple individually, quote them
var words = name.Split(' ');
if (words.Length <= 3 && words.All(w => w.Length > 0 && IsSimple(w)))
// Words with double quotes are never "simple" so we're safe to naive-quote here
return $"\"{name}\"";
// Otherwise, just use hid
return hid;
}

View File

@@ -7,7 +7,7 @@ using Sentry;
namespace PluralKit.Bot
{
public interface ISentryEnricher<T> where T: IGatewayEvent
public interface ISentryEnricher<T> where T : IGatewayEvent
{
void Enrich(Scope scope, Shard shard, T evt);
}
@@ -25,10 +25,10 @@ namespace PluralKit.Bot
{
_bot = bot;
}
// TODO: should this class take the Scope by dependency injection instead?
// Would allow us to create a centralized "chain of handlers" where this class could just be registered as an entry in
public void Enrich(Scope scope, Shard shard, MessageCreateEvent evt)
{
scope.AddBreadcrumb(evt.Content, "event.message", data: new Dictionary<string, string>

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Myriad.Cache;
using Myriad.Extensions;
@@ -26,14 +26,14 @@ namespace PluralKit.Bot
{
new("ShardId", new ScalarValue(shard.ShardId)),
};
var (guild, channel) = GetGuildChannelId(evt);
var user = GetUserId(evt);
var message = GetMessageId(evt);
if (guild != null)
props.Add(new("GuildId", new ScalarValue(guild.Value)));
if (channel != null)
{
props.Add(new("ChannelId", new ScalarValue(channel.Value)));
@@ -44,10 +44,10 @@ namespace PluralKit.Bot
props.Add(new("BotPermissions", new ScalarValue(botPermissions)));
}
}
if (message != null)
props.Add(new("MessageId", new ScalarValue(message.Value)));
if (user != null)
props.Add(new("UserId", new ScalarValue(user.Value)));
@@ -56,7 +56,7 @@ namespace PluralKit.Bot
return new Inner(props);
}
private (ulong?, ulong?) GetGuildChannelId(IGatewayEvent evt) => evt switch
{
ChannelCreateEvent e => (e.GuildId, e.Id),
@@ -101,7 +101,7 @@ namespace PluralKit.Bot
{
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
foreach (var prop in Properties)
foreach (var prop in Properties)
logEvent.AddPropertyIfAbsent(prop);
}
}