Browse Source

Add invite events (create and delete)

pull/1491/head
Paulo 5 years ago
parent
commit
9b438768bc
6 changed files with 257 additions and 0 deletions
  1. +27
    -0
      src/Discord.Net.WebSocket/API/Gateway/InviteCreateEvent.cs
  2. +14
    -0
      src/Discord.Net.WebSocket/API/Gateway/InviteDeleteEvent.cs
  3. +18
    -0
      src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
  4. +3
    -0
      src/Discord.Net.WebSocket/DiscordShardedClient.cs
  5. +58
    -0
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  6. +137
    -0
      src/Discord.Net.WebSocket/Entities/Invites/SocketInvite.cs

+ 27
- 0
src/Discord.Net.WebSocket/API/Gateway/InviteCreateEvent.cs View File

@@ -0,0 +1,27 @@
using Newtonsoft.Json;
using System;

namespace Discord.API.Gateway
{
internal class InviteCreateEvent
{
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("created_at")]
public DateTimeOffset CreatedAt { get; set; }
[JsonProperty("guild_id")]
public Optional<ulong> GuildId { get; set; }
[JsonProperty("inviter")]
public Optional<User> Inviter { get; set; }
[JsonProperty("max_age")]
public int MaxAge { get; set; }
[JsonProperty("max_uses")]
public int MaxUses { get; set; }
[JsonProperty("temporary")]
public bool Temporary { get; set; }
[JsonProperty("uses")]
public int Uses { get; set; }
}
}

+ 14
- 0
src/Discord.Net.WebSocket/API/Gateway/InviteDeleteEvent.cs View File

@@ -0,0 +1,14 @@
using Newtonsoft.Json;

namespace Discord.API.Gateway
{
internal class InviteDeleteEvent
{
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("guild_id")]
public Optional<ulong> GuildId { get; set; }
}
}

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

@@ -1,3 +1,4 @@
using Discord.API;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -367,5 +368,22 @@ namespace Discord.WebSocket
remove { _recipientRemovedEvent.Remove(value); }
}
internal readonly AsyncEvent<Func<SocketGroupUser, Task>> _recipientRemovedEvent = new AsyncEvent<Func<SocketGroupUser, Task>>();

//Invites
/// <summary> Fired when an invite is created. </summary>
public event Func<SocketInvite, Task> InviteCreated
{
add { _inviteCreatedEvent.Add(value); }
remove { _inviteCreatedEvent.Remove(value); }
}
internal readonly AsyncEvent<Func<SocketInvite, Task>> _inviteCreatedEvent = new AsyncEvent<Func<SocketInvite, Task>>();
/// <summary> Fired when an invite is deleted. </summary>
/// <remarks> The string is the invite code. </remarks>
public event Func<SocketGuildChannel, string, Task> InviteDeleted
{
add { _inviteDeletedEvent.Add(value); }
remove { _inviteDeletedEvent.Remove(value); }
}
internal readonly AsyncEvent<Func<SocketGuildChannel, string, Task>> _inviteDeletedEvent = new AsyncEvent<Func<SocketGuildChannel, string, Task>>();
}
}

+ 3
- 0
src/Discord.Net.WebSocket/DiscordShardedClient.cs View File

@@ -337,6 +337,9 @@ namespace Discord.WebSocket
client.UserIsTyping += (oldUser, newUser) => _userIsTypingEvent.InvokeAsync(oldUser, newUser);
client.RecipientAdded += (user) => _recipientAddedEvent.InvokeAsync(user);
client.RecipientRemoved += (user) => _recipientRemovedEvent.InvokeAsync(user);

client.InviteCreated += (invite) => _inviteCreatedEvent.InvokeAsync(invite);
client.InviteDeleted += (channel, invite) => _inviteDeletedEvent.InvokeAsync(channel, invite);
}

//IDiscordClient


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

@@ -1635,6 +1635,64 @@ namespace Discord.WebSocket
}
break;

//Invites
case "INVITE_CREATE":
{
await _gatewayLogger.DebugAsync("Received Dispatch (INVITE_CREATE)").ConfigureAwait(false);

var data = (payload as JToken).ToObject<API.Gateway.InviteCreateEvent>(_serializer);
if (State.GetChannel(data.ChannelId) is SocketGuildChannel channel)
{
var guild = channel.Guild;
if (!guild.IsSynced)
{
await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false);
return;
}

SocketGuildUser inviter = null;
if (data.Inviter.IsSpecified)
{
inviter = guild.GetUser(data.Inviter.Value.Id);
if (inviter == null)
inviter = guild.AddOrUpdateUser(data.Inviter.Value);
}

var invite = SocketInvite.Create(this, guild, channel, inviter, data);

await TimedInvokeAsync(_inviteCreatedEvent, nameof(InviteCreated), invite).ConfigureAwait(false);
}
else
{
await UnknownChannelAsync(type, data.ChannelId).ConfigureAwait(false);
return;
}
}
break;
case "INVITE_DELETE":
{
await _gatewayLogger.DebugAsync("Received Dispatch (INVITE_DELETE)").ConfigureAwait(false);

var data = (payload as JToken).ToObject<API.Gateway.InviteDeleteEvent>(_serializer);
if (State.GetChannel(data.ChannelId) is SocketGuildChannel channel)
{
var guild = channel.Guild;
if (!guild.IsSynced)
{
await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false);
return;
}

await TimedInvokeAsync(_inviteDeletedEvent, nameof(InviteDeleted), channel, data.Code).ConfigureAwait(false);
}
else
{
await UnknownChannelAsync(type, data.ChannelId).ConfigureAwait(false);
return;
}
}
break;

//Ignored (User only)
case "CHANNEL_PINS_ACK":
await _gatewayLogger.DebugAsync("Ignored Dispatch (CHANNEL_PINS_ACK)").ConfigureAwait(false);


+ 137
- 0
src/Discord.Net.WebSocket/Entities/Invites/SocketInvite.cs View File

@@ -0,0 +1,137 @@
using Discord.Rest;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Model = Discord.API.Gateway.InviteCreateEvent;

namespace Discord.WebSocket
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketInvite : SocketEntity<string>, IInviteMetadata
{
private long _createdAtTicks;

/// <inheritdoc />
public ulong ChannelId { get; private set; }
/// <summary>
/// Gets the channel where this invite was created.
/// </summary>
public SocketGuildChannel Channel { get; private set; }
/// <inheritdoc />
public ulong? GuildId { get; private set; }
/// <summary>
/// Gets the guild where this invite was created.
/// </summary>
public SocketGuild Guild { get; private set; }
/// <inheritdoc />
ChannelType IInvite.ChannelType => throw new NotImplementedException();
/// <inheritdoc />
string IInvite.ChannelName => throw new NotImplementedException();
/// <inheritdoc />
string IInvite.GuildName => throw new NotImplementedException();
/// <inheritdoc />
int? IInvite.PresenceCount => throw new NotImplementedException();
/// <inheritdoc />
int? IInvite.MemberCount => throw new NotImplementedException();
/// <inheritdoc />
bool IInviteMetadata.IsRevoked => throw new NotImplementedException();
/// <inheritdoc />
public bool IsTemporary { get; private set; }
/// <inheritdoc />
int? IInviteMetadata.MaxAge { get => MaxAge; }
/// <inheritdoc />
int? IInviteMetadata.MaxUses { get => MaxUses; }
/// <inheritdoc />
int? IInviteMetadata.Uses { get => Uses; }
/// <summary>
/// Gets the time (in seconds) until the invite expires.
/// </summary>
public int MaxAge { get; private set; }
/// <summary>
/// Gets the max number of uses this invite may have.
/// </summary>
public int MaxUses { get; private set; }
/// <summary>
/// Gets the number of times this invite has been used.
/// </summary>
public int Uses { get; private set; }
/// <summary>
/// Gets the user that created this invite if available.
/// </summary>
public SocketGuildUser Inviter { get; private set; }
/// <inheritdoc />
DateTimeOffset? IInviteMetadata.CreatedAt => DateTimeUtils.FromTicks(_createdAtTicks);
/// <summary>
/// Gets when this invite was created.
/// </summary>
public DateTimeOffset CreatedAt => DateTimeUtils.FromTicks(_createdAtTicks);

/// <inheritdoc />
public string Code => Id;
/// <inheritdoc />
public string Url => $"{DiscordConfig.InviteUrl}{Code}";

internal SocketInvite(DiscordSocketClient discord, SocketGuild guild, SocketGuildChannel channel, SocketGuildUser inviter, string id)
: base(discord, id)
{
Guild = guild;
Channel = channel;
Inviter = inviter;
}
internal static SocketInvite Create(DiscordSocketClient discord, SocketGuild guild, SocketGuildChannel channel, SocketGuildUser inviter, Model model)
{
var entity = new SocketInvite(discord, guild, channel, inviter, model.Code);
entity.Update(model);
return entity;
}
internal void Update(Model model)
{
ChannelId = model.ChannelId;
GuildId = model.GuildId.IsSpecified ? model.GuildId.Value : Guild.Id;
IsTemporary = model.Temporary;
MaxAge = model.MaxAge;
MaxUses = model.MaxUses;
Uses = model.Uses;
_createdAtTicks = model.CreatedAt.UtcTicks;
}

/// <inheritdoc />
public Task DeleteAsync(RequestOptions options = null)
=> InviteHelper.DeleteAsync(this, Discord, options);

/// <summary>
/// Gets the URL of the invite.
/// </summary>
/// <returns>
/// A string that resolves to the Url of the invite.
/// </returns>
public override string ToString() => Url;
private string DebuggerDisplay => $"{Url} ({Guild?.Name} / {Channel.Name})";

/// <inheritdoc />
IGuild IInvite.Guild
{
get
{
if (Guild != null)
return Guild;
if (Channel is IGuildChannel guildChannel)
return guildChannel.Guild; //If it fails, it'll still return this exception
throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object.");
}
}
/// <inheritdoc />
IChannel IInvite.Channel
{
get
{
if (Channel != null)
return Channel;
throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object.");
}
}

/// <inheritdoc />
IUser IInviteMetadata.Inviter => Inviter;
}
}

Loading…
Cancel
Save