Browse Source

Add GUILD_SCHEDULED_EVENT_USER_ADD and GUILD_SCHEDULED_EVENT_USER_REMOVE (#287)

pull/1923/head
quin lynch 3 years ago
parent
commit
790187752c
4 changed files with 136 additions and 0 deletions
  1. +56
    -0
      src/Discord.Net.Core/Utils/Cacheable.cs
  2. +19
    -0
      src/Discord.Net.WebSocket/API/Gateway/GuildScheduledEventUserAddRemoveEvent.cs
  3. +16
    -0
      src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
  4. +45
    -0
      src/Discord.Net.WebSocket/DiscordSocketClient.cs

+ 56
- 0
src/Discord.Net.Core/Utils/Cacheable.cs View File

@@ -63,4 +63,60 @@ namespace Discord
/// </returns>
public async Task<TEntity> GetOrDownloadAsync() => HasValue ? Value : await DownloadAsync().ConfigureAwait(false);
}
public struct Cacheable<TCachedEntity, TDownloadableEntity, TRelationship, TId>
where TCachedEntity : IEntity<TId>, TRelationship
where TDownloadableEntity : IEntity<TId>, TRelationship
where TId : IEquatable<TId>
{
/// <summary>
/// Gets whether this entity is cached.
/// </summary>
public bool HasValue { get; }
/// <summary>
/// Gets the ID of this entity.
/// </summary>
public TId Id { get; }
/// <summary>
/// Gets the entity if it could be pulled from cache.
/// </summary>
/// <remarks>
/// This value is not guaranteed to be set; in cases where the entity cannot be pulled from cache, it is
/// <c>null</c>.
/// </remarks>
public TCachedEntity Value { get; }
private Func<Task<TDownloadableEntity>> DownloadFunc { get; }

internal Cacheable(TCachedEntity value, TId id, bool hasValue, Func<Task<TDownloadableEntity>> downloadFunc)
{
Value = value;
Id = id;
HasValue = hasValue;
DownloadFunc = downloadFunc;
}

/// <summary>
/// Downloads this entity.
/// </summary>
/// <exception cref="Discord.Net.HttpException">Thrown when used from a user account.</exception>
/// <exception cref="NullReferenceException">Thrown when the message is deleted.</exception>
/// <returns>
/// A task that represents the asynchronous download operation. The task result contains the downloaded
/// entity.
/// </returns>
public async Task<TDownloadableEntity> DownloadAsync()
{
return await DownloadFunc().ConfigureAwait(false);
}

/// <summary>
/// Returns the cached entity if it exists; otherwise downloads it.
/// </summary>
/// <exception cref="Discord.Net.HttpException">Thrown when used from a user account.</exception>
/// <exception cref="NullReferenceException">Thrown when the message is deleted and is not in cache.</exception>
/// <returns>
/// A task that represents the asynchronous operation that attempts to get the message via cache or to
/// download the message. The task result contains the downloaded entity.
/// </returns>
public async Task<TRelationship> GetOrDownloadAsync() => HasValue ? Value : await DownloadAsync().ConfigureAwait(false);
}
}

+ 19
- 0
src/Discord.Net.WebSocket/API/Gateway/GuildScheduledEventUserAddRemoveEvent.cs View File

@@ -0,0 +1,19 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord.API.Gateway
{
internal class GuildScheduledEventUserAddRemoveEvent
{
[JsonProperty("guild_scheduled_event_id")]
public ulong EventId { get; set; }
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("user_id")]
public ulong UserId { get; set; }
}
}

+ 16
- 0
src/Discord.Net.WebSocket/BaseSocketClient.Events.cs View File

@@ -1,3 +1,4 @@
using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -397,6 +398,21 @@ namespace Discord.WebSocket
}
internal readonly AsyncEvent<Func<SocketGuildEvent, Task>> _guildScheduledEventStarted = new AsyncEvent<Func<SocketGuildEvent, Task>>();

public event Func<Cacheable<SocketUser, RestUser, IUser, ulong>, SocketGuildEvent, Task> GuildScheduledEventUserAdd
{
add { _guildScheduledEventUserAdd.Add(value); }
remove { _guildScheduledEventUserAdd.Remove(value); }
}
internal readonly AsyncEvent<Func<Cacheable<SocketUser, RestUser, IUser, ulong>, SocketGuildEvent, Task>> _guildScheduledEventUserAdd = new AsyncEvent<Func<Cacheable<SocketUser, RestUser, IUser, ulong>, SocketGuildEvent, Task>>();

public event Func<Cacheable<SocketUser, RestUser, IUser, ulong>, SocketGuildEvent, Task> GuildScheduledEventUserRemove
{
add { _guildScheduledEventUserRemove.Add(value); }
remove { _guildScheduledEventUserRemove.Remove(value); }
}
internal readonly AsyncEvent<Func<Cacheable<SocketUser, RestUser, IUser, ulong>, SocketGuildEvent, Task>> _guildScheduledEventUserRemove = new AsyncEvent<Func<Cacheable<SocketUser, RestUser, IUser, ulong>, SocketGuildEvent, Task>>();


#endregion

#region Users


+ 45
- 0
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -2597,6 +2597,7 @@ namespace Discord.WebSocket
}

var before = guild.GetEvent(data.Id);

var beforeCacheable = new Cacheable<SocketGuildEvent, ulong>(before, data.Id, before != null, () => Task.FromResult((SocketGuildEvent)null));

var after = guild.AddOrUpdateEvent(data);
@@ -2631,6 +2632,44 @@ namespace Discord.WebSocket
await TimedInvokeAsync(_guildScheduledEventCancelled, nameof(GuildScheduledEventCancelled), guildEvent).ConfigureAwait(false);
}
break;
case "GUILD_SCHEDULED_EVENT_USER_ADD" or "GUILD_SCHEDULED_EVENT_USER_REMOVE":
{
await _gatewayLogger.DebugAsync($"Received Dispatch ({type})").ConfigureAwait(false);

var data = (payload as JToken).ToObject<GuildScheduledEventUserAddRemoveEvent>(_serializer);

var guild = State.GetGuild(data.GuildId);

if(guild == null)
{
await UnknownGuildAsync(type, data.GuildId).ConfigureAwait(false);
return;
}

var guildEvent = guild.GetEvent(data.EventId);

if (guildEvent == null)
{
await UnknownGuildEventAsync(type, data.EventId, data.GuildId).ConfigureAwait(false);
return;
}

var user = (SocketUser)guild.GetUser(data.UserId) ?? State.GetUser(data.UserId);

var cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(user, data.UserId, user != null, () => Rest.GetUserAsync(data.UserId));

switch (type)
{
case "GUILD_SCHEDULED_EVENT_USER_ADD":
await TimedInvokeAsync(_guildScheduledEventUserAdd, nameof(GuildScheduledEventUserAdd), cacheableUser, guildEvent).ConfigureAwait(false);
break;
case "GUILD_SCHEDULED_EVENT_USER_REMOVE":
await TimedInvokeAsync(_guildScheduledEventUserRemove, nameof(GuildScheduledEventUserRemove), cacheableUser, guildEvent).ConfigureAwait(false);
break;
}

}
break;

#endregion

@@ -2947,6 +2986,12 @@ namespace Discord.WebSocket
string details = $"{evnt} Guild={guildId}";
await _gatewayLogger.WarningAsync($"Unknown Guild ({details}).").ConfigureAwait(false);
}

private async Task UnknownGuildEventAsync(string evnt, ulong eventId, ulong guildId)
{
string details = $"{evnt} Event={eventId} Guild={guildId}";
await _gatewayLogger.WarningAsync($"Unknown Guild Event ({details}).").ConfigureAwait(false);
}
private async Task UnsyncedGuildAsync(string evnt, ulong guildId)
{
string details = $"{evnt} Guild={guildId}";


Loading…
Cancel
Save