mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-10 15:57:53 +00:00
feat: remote await events from gateway
This commit is contained in:
parent
64ff69723c
commit
15c992c572
17 changed files with 439 additions and 30 deletions
|
|
@ -26,6 +26,7 @@ public class BotConfig
|
|||
|
||||
public string? HttpListenerAddr { get; set; }
|
||||
public bool DisableGateway { get; set; } = false;
|
||||
public string? EventAwaiterTarget { get; set; }
|
||||
|
||||
public string? DiscordBaseUrl { get; set; }
|
||||
public string? AvatarServiceUrl { get; set; }
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public abstract class BaseInteractive
|
|||
ButtonStyle style = ButtonStyle.Secondary, bool disabled = false)
|
||||
{
|
||||
var dispatch = _ctx.Services.Resolve<InteractionDispatchService>();
|
||||
var customId = dispatch.Register(handler, Timeout);
|
||||
var customId = dispatch.Register(_ctx.ShardId, handler, Timeout);
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
|
|
@ -89,7 +89,7 @@ public abstract class BaseInteractive
|
|||
{
|
||||
var dispatch = ctx.Services.Resolve<InteractionDispatchService>();
|
||||
foreach (var button in _buttons)
|
||||
button.CustomId = dispatch.Register(button.Handler, Timeout);
|
||||
button.CustomId = dispatch.Register(_ctx.ShardId, button.Handler, Timeout);
|
||||
}
|
||||
|
||||
public abstract Task Start();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Autofac;
|
||||
|
||||
using Myriad.Cache;
|
||||
using Myriad.Gateway;
|
||||
using Myriad.Rest.Types;
|
||||
using Myriad.Types;
|
||||
|
|
@ -69,6 +70,9 @@ public class YesNoPrompt: BaseInteractive
|
|||
return true;
|
||||
}
|
||||
|
||||
// no need to reawait message
|
||||
// gateway will already have sent us only matching messages
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +92,17 @@ public class YesNoPrompt: BaseInteractive
|
|||
{
|
||||
try
|
||||
{
|
||||
// check if http gateway and set listener
|
||||
// todo: this one needs to handle options for message
|
||||
if (_ctx.Cache is HttpDiscordCache)
|
||||
await (_ctx.Cache as HttpDiscordCache).AwaitMessage(
|
||||
_ctx.Guild?.Id ?? 0,
|
||||
_ctx.Channel.Id,
|
||||
_ctx.Author.Id,
|
||||
Timeout,
|
||||
options: new[] { "yes", "y", "no", "n" }
|
||||
);
|
||||
|
||||
await queue.WaitFor(MessagePredicate, Timeout, cts.Token);
|
||||
}
|
||||
catch (TimeoutException e)
|
||||
|
|
|
|||
|
|
@ -49,8 +49,15 @@ public class BotModule: Module
|
|||
|
||||
if (botConfig.HttpCacheUrl != null)
|
||||
{
|
||||
var cache = new HttpDiscordCache(c.Resolve<ILogger>(),
|
||||
c.Resolve<HttpClient>(), botConfig.HttpCacheUrl, botConfig.Cluster?.TotalShards ?? 1, botConfig.ClientId, botConfig.HttpUseInnerCache);
|
||||
var cache = new HttpDiscordCache(
|
||||
c.Resolve<ILogger>(),
|
||||
c.Resolve<HttpClient>(),
|
||||
botConfig.HttpCacheUrl,
|
||||
botConfig.EventAwaiterTarget,
|
||||
botConfig.Cluster?.TotalShards ?? 1,
|
||||
botConfig.ClientId,
|
||||
botConfig.HttpUseInnerCache
|
||||
);
|
||||
|
||||
var metrics = c.Resolve<IMetrics>();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using System.Collections.Concurrent;
|
||||
|
||||
using Myriad.Cache;
|
||||
|
||||
using NodaTime;
|
||||
|
||||
using Serilog;
|
||||
|
|
@ -16,9 +18,12 @@ public class InteractionDispatchService: IDisposable
|
|||
private readonly ConcurrentDictionary<Guid, RegisteredInteraction> _handlers = new();
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public InteractionDispatchService(IClock clock, ILogger logger)
|
||||
private readonly IDiscordCache _cache;
|
||||
|
||||
public InteractionDispatchService(IClock clock, ILogger logger, IDiscordCache cache)
|
||||
{
|
||||
_clock = clock;
|
||||
_cache = cache;
|
||||
_logger = logger.ForContext<InteractionDispatchService>();
|
||||
|
||||
_cleanupWorker = CleanupLoop(_cts.Token);
|
||||
|
|
@ -50,9 +55,15 @@ public class InteractionDispatchService: IDisposable
|
|||
_handlers.TryRemove(customIdGuid, out _);
|
||||
}
|
||||
|
||||
public string Register(Func<InteractionContext, Task> callback, Duration? expiry = null)
|
||||
public string Register(int shardId, Func<InteractionContext, Task> callback, Duration? expiry = null)
|
||||
{
|
||||
var key = Guid.NewGuid();
|
||||
|
||||
// if http_cache, return RegisterRemote
|
||||
// not awaited here, it's probably fine
|
||||
if (_cache is HttpDiscordCache)
|
||||
(_cache as HttpDiscordCache).AwaitInteraction(shardId, key.ToString(), expiry);
|
||||
|
||||
var handler = new RegisteredInteraction
|
||||
{
|
||||
Callback = callback,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Autofac;
|
||||
|
||||
using Myriad.Builders;
|
||||
using Myriad.Cache;
|
||||
using Myriad.Gateway;
|
||||
using Myriad.Rest.Exceptions;
|
||||
using Myriad.Rest.Types.Requests;
|
||||
|
|
@ -40,8 +41,12 @@ public static class ContextUtils
|
|||
}
|
||||
|
||||
public static async Task<MessageReactionAddEvent> AwaitReaction(this Context ctx, Message message,
|
||||
User user = null, Func<MessageReactionAddEvent, bool> predicate = null, Duration? timeout = null)
|
||||
User user, Func<MessageReactionAddEvent, bool> predicate = null, Duration? timeout = null)
|
||||
{
|
||||
// check if http gateway and set listener
|
||||
if (ctx.Cache is HttpDiscordCache)
|
||||
await (ctx.Cache as HttpDiscordCache).AwaitReaction(ctx.Guild?.Id ?? 0, message.Id, user!.Id, timeout);
|
||||
|
||||
bool ReactionPredicate(MessageReactionAddEvent evt)
|
||||
{
|
||||
if (message.Id != evt.MessageId) return false; // Ignore reactions for different messages
|
||||
|
|
@ -57,11 +62,17 @@ public static class ContextUtils
|
|||
|
||||
public static async Task<bool> ConfirmWithReply(this Context ctx, string expectedReply, bool treatAsHid = false)
|
||||
{
|
||||
var timeout = Duration.FromMinutes(1);
|
||||
|
||||
// check if http gateway and set listener
|
||||
if (ctx.Cache is HttpDiscordCache)
|
||||
await (ctx.Cache as HttpDiscordCache).AwaitMessage(ctx.Guild?.Id ?? 0, ctx.Channel.Id, ctx.Author.Id, timeout);
|
||||
|
||||
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));
|
||||
.WaitFor(Predicate, timeout);
|
||||
|
||||
var content = msg.Content;
|
||||
if (treatAsHid)
|
||||
|
|
@ -96,11 +107,17 @@ public static class ContextUtils
|
|||
|
||||
async Task<int> PromptPageNumber()
|
||||
{
|
||||
var timeout = Duration.FromMinutes(0.5);
|
||||
|
||||
// check if http gateway and set listener
|
||||
if (ctx.Cache is HttpDiscordCache)
|
||||
await (ctx.Cache as HttpDiscordCache).AwaitMessage(ctx.Guild?.Id ?? 0, ctx.Channel.Id, ctx.Author.Id, timeout);
|
||||
|
||||
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(0.5));
|
||||
.WaitFor(Predicate, timeout);
|
||||
|
||||
int.TryParse(msg.Content, out var num);
|
||||
|
||||
|
|
|
|||
|
|
@ -764,6 +764,8 @@
|
|||
"myriad": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"NodaTime": "[3.2.0, )",
|
||||
"NodaTime.Serialization.JsonNet": "[3.1.0, )",
|
||||
"Polly": "[8.5.0, )",
|
||||
"Polly.Contrib.WaitAndRetry": "[1.1.1, )",
|
||||
"Serilog": "[4.2.0, )",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue