From 73de20b615c487464085c26140bad8f63a5bd7c5 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 6 Jan 2022 22:41:49 +0100 Subject: [PATCH] Stagger greet dms --- src/NadekoBot/.editorconfig | 4 +- .../Common/Replacements/ReplacementBuilder.cs | 2 + .../Administration/GreetBye/GreetCommands.cs | 3 +- .../Administration/GreetBye/GreetService.cs | 54 ++++++++++++++----- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/NadekoBot/.editorconfig b/src/NadekoBot/.editorconfig index cf85ce77f..ead66194d 100644 --- a/src/NadekoBot/.editorconfig +++ b/src/NadekoBot/.editorconfig @@ -335,7 +335,8 @@ resharper_csharp_wrap_before_binary_opsign = true resharper_csharp_wrap_before_invocation_rpar = false resharper_csharp_wrap_parameters_style = chop_if_long resharper_force_chop_compound_if_expression = false -resharper_keep_existing_linebreaks = false +resharper_keep_existing_linebreaks = true +resharper_keep_user_linebreaks = true resharper_max_formal_parameters_on_line = 3 resharper_place_simple_embedded_statement_on_same_line = false resharper_wrap_chained_binary_expressions = chop_if_long @@ -347,3 +348,4 @@ resharper_csharp_place_type_constraints_on_same_line = false resharper_csharp_wrap_before_extends_colon = true resharper_csharp_place_constructor_initializer_on_same_line = false resharper_force_attribute_style = separate +resharper_braces_for_ifelse = required_for_multiline diff --git a/src/NadekoBot/Common/Replacements/ReplacementBuilder.cs b/src/NadekoBot/Common/Replacements/ReplacementBuilder.cs index 8246fc6c5..2b52fe87d 100644 --- a/src/NadekoBot/Common/Replacements/ReplacementBuilder.cs +++ b/src/NadekoBot/Common/Replacements/ReplacementBuilder.cs @@ -63,8 +63,10 @@ public class ReplacementBuilder { var to = TimeZoneInfo.Local; if (g is not null) + { if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz)) to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local; + } return TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Utc, to).ToString("HH:mm ") + to.StandardName.GetInitials(); diff --git a/src/NadekoBot/Modules/Administration/GreetBye/GreetCommands.cs b/src/NadekoBot/Modules/Administration/GreetBye/GreetCommands.cs index 59bdf509c..cdeb3e6aa 100644 --- a/src/NadekoBot/Modules/Administration/GreetBye/GreetCommands.cs +++ b/src/NadekoBot/Modules/Administration/GreetBye/GreetCommands.cs @@ -214,8 +214,7 @@ public partial class Administration { user ??= (IGuildUser)ctx.User; - var channel = await user.CreateDMChannelAsync(); - var success = await _service.GreetDmTest(channel, user); + var success = await _service.GreetDmTest(user); if (success) await ctx.OkAsync(); else diff --git a/src/NadekoBot/Modules/Administration/GreetBye/GreetService.cs b/src/NadekoBot/Modules/Administration/GreetBye/GreetService.cs index 395bbb589..6401676fb 100644 --- a/src/NadekoBot/Modules/Administration/GreetBye/GreetService.cs +++ b/src/NadekoBot/Modules/Administration/GreetBye/GreetService.cs @@ -1,9 +1,11 @@ +using NadekoBot.Common.ModuleBehaviors; using NadekoBot.Db; using NadekoBot.Services.Database.Models; +using System.Threading.Channels; namespace NadekoBot.Services; -public class GreetService : INService +public class GreetService : INService, IReadyExecutor { public bool GroupGreets => _bss.Data.GroupGreets; @@ -38,6 +40,17 @@ public class GreetService : INService _client.GuildMemberUpdated += ClientOnGuildMemberUpdated; } + public async Task OnReadyAsync() + { + while (true) + { + var (conf, user, compl) = await _greetDmQueue.Reader.ReadAsync(); + var res = await GreetDmUserInternal(conf, user); + compl.TrySetResult(res); + await Task.Delay(2000); + } + } + private Task ClientOnGuildMemberUpdated(Cacheable optOldUser, SocketGuildUser newUser) { // if user is a new booster @@ -209,14 +222,33 @@ public class GreetService : INService } } - private async Task GreetDmUser(GreetSettings conf, IDMChannel channel, IGuildUser user) + private readonly Channel<(GreetSettings, IGuildUser, TaskCompletionSource)> _greetDmQueue = + Channel.CreateBounded<(GreetSettings, IGuildUser, TaskCompletionSource)>(new BoundedChannelOptions(60) + { + // The limit of 60 users should be only hit when there's a raid. In that case + // probably the best thing to do is to drop newest (raiding) users + FullMode = BoundedChannelFullMode.DropNewest + }); + + private async Task GreetDmUser(GreetSettings conf, IGuildUser user) + { + var completionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + await _greetDmQueue.Writer.WriteAsync((conf, user, completionSource)); + return await completionSource.Task; + } + + private async Task GreetDmUserInternal(GreetSettings conf, IGuildUser user) { - var rep = new ReplacementBuilder().WithDefault(user, channel, (SocketGuild)user.Guild, _client).Build(); - - var text = SmartText.CreateFrom(conf.DmGreetMessageText); - text = rep.Replace(text); try { + var rep = new ReplacementBuilder() + .WithUser(user) + .WithServer(_client, (SocketGuild)user.Guild) + .Build(); + + var text = SmartText.CreateFrom(conf.DmGreetMessageText); + text = rep.Replace(text); + if (text is SmartPlainText pt) { text = new SmartEmbedText() { PlainText = pt.Text }; @@ -227,7 +259,7 @@ public class GreetService : INService Text = $"This message was sent from {user.Guild} server.", IconUrl = user.Guild.IconUrl }; - await channel.SendAsync(text); + await user.SendAsync(text); } catch { @@ -277,9 +309,7 @@ public class GreetService : INService if (conf.SendDmGreetMessage) { - var channel = await user.CreateDMChannelAsync(); - - if (channel is not null) await GreetDmUser(conf, channel, user); + await GreetDmUser(conf, user); } } catch @@ -551,10 +581,10 @@ public class GreetService : INService return GreetUsers(conf, channel, user); } - public Task GreetDmTest(IDMChannel channel, IGuildUser user) + public Task GreetDmTest(IGuildUser user) { var conf = GetOrAddSettingsForGuild(user.GuildId); - return GreetDmUser(conf, channel, user); + return GreetDmUser(conf, user); } #endregion