.greetdm staggering to avoid ratelimits during raids

This commit is contained in:
Kwoth
2022-01-06 22:53:59 +01:00
parent 22183501fe
commit c0ce22a6b7
2 changed files with 47 additions and 19 deletions

View File

@@ -258,8 +258,7 @@ namespace NadekoBot.Modules.Administration
{
user = user ?? (IGuildUser) ctx.User;
var channel = await user.GetOrCreateDMChannelAsync();
var success = await _service.GreetDmTest(channel, user);
var success = await _service.GreetDmTest(user);
if (success)
await ctx.OkAsync();
else

View File

@@ -8,14 +8,16 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;
using System.Threading.Tasks;
using NadekoBot.Common.ModuleBehaviors;
using NadekoBot.Db;
using NadekoBot.Modules.Administration;
using Serilog;
namespace NadekoBot.Services
{
public class GreetSettingsService : INService
public class GreetSettingsService : INService, IReadyExecutor
{
private readonly DbService _db;
@@ -51,6 +53,17 @@ namespace NadekoBot.Services
_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(SocketGuildUser oldUser, SocketGuildUser newUser)
{
@@ -240,16 +253,33 @@ namespace NadekoBot.Services
}
}
private async Task<bool> GreetDmUser(GreetSettings conf, IDMChannel channel, IGuildUser user)
private readonly Channel<(GreetSettings, IGuildUser, TaskCompletionSource<bool>)> _greetDmQueue =
Channel.CreateBounded<(GreetSettings, IGuildUser, TaskCompletionSource<bool>)>(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<bool> GreetDmUser(GreetSettings conf, IGuildUser user)
{
var completionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
await _greetDmQueue.Writer.WriteAsync((conf, user, completionSource));
return await completionSource.Task;
}
private async Task<bool> GreetDmUserInternal(GreetSettings conf, IGuildUser user)
{
var rep = new ReplacementBuilder()
.WithDefault(user, channel, (SocketGuild)user.Guild, _client)
.Build();
var text = SmartText.CreateFrom(conf.DmGreetMessageText);
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 };
@@ -259,8 +289,12 @@ namespace NadekoBot.Services
{
Text = $"This message was sent from {user.Guild} server.", IconUrl = user.Guild.IconUrl
};
var ch = await user.GetOrCreateDMChannelAsync();
if (ch is null)
return false;
await channel.SendAsync(text).ConfigureAwait(false);
await ch.SendAsync(text);
}
catch
{
@@ -311,12 +345,7 @@ namespace NadekoBot.Services
if (conf.SendDmGreetMessage)
{
var channel = await user.GetOrCreateDMChannelAsync().ConfigureAwait(false);
if (channel != null)
{
await GreetDmUser(conf, channel, user);
}
await GreetDmUser(conf, user);
}
}
catch
@@ -487,10 +516,10 @@ namespace NadekoBot.Services
return GreetUsers(conf, channel, user);
}
public Task<bool> GreetDmTest(IDMChannel channel, IGuildUser user)
public Task<bool> GreetDmTest(IGuildUser user)
{
var conf = GetOrAddSettingsForGuild(user.GuildId);
return GreetDmUser(conf, channel, user);
return GreetDmUser(conf, user);
}
#endregion