Browse Source

Add SocketUnknownChannel

pull/1902/head
Paulo 3 years ago
parent
commit
3190a1a8e9
3 changed files with 232 additions and 6 deletions
  1. +8
    -6
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  2. +2
    -0
      src/Discord.Net.WebSocket/Entities/Channels/SocketChannelHelper.cs
  3. +222
    -0
      src/Discord.Net.WebSocket/Entities/Channels/SocketUnknownChannel.cs

+ 8
- 6
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -1262,7 +1262,7 @@ namespace Discord.WebSocket
var data = (payload as JToken).ToObject<API.Message>(_serializer);
var channel = GetChannel(data.ChannelId) as ISocketMessageChannel;

var guild = (channel as SocketGuildChannel)?.Guild;
var guild = data.GuildId.IsSpecified ? State.GetGuild(data.GuildId.Value) : null;
if (guild != null && !guild.IsSynced)
{
await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false);
@@ -1277,8 +1277,7 @@ namespace Discord.WebSocket
}
else
{
await UnknownChannelAsync(type, data.ChannelId).ConfigureAwait(false);
return;
channel = CreateUnknownChannel(data.ChannelId, data.GuildId.IsSpecified ? data.GuildId.Value : null, State);
}
}

@@ -1326,7 +1325,7 @@ namespace Discord.WebSocket
var data = (payload as JToken).ToObject<API.Message>(_serializer);
var channel = GetChannel(data.ChannelId) as ISocketMessageChannel;

var guild = (channel as SocketGuildChannel)?.Guild;
var guild = data.GuildId.IsSpecified ? State.GetGuild(data.GuildId.Value) : null;
if (guild != null && !guild.IsSynced)
{
await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false);
@@ -1393,8 +1392,7 @@ namespace Discord.WebSocket
}
else
{
await UnknownChannelAsync(type, data.ChannelId).ConfigureAwait(false);
return;
channel = CreateUnknownChannel(data.ChannelId, data.GuildId.IsSpecified ? data.GuildId.Value : null, State);
}
}

@@ -2017,6 +2015,10 @@ namespace Discord.WebSocket
foreach (var channel in channels)
channel.Recipient.GlobalUser.RemoveRef(this);
}
internal SocketUnknownChannel CreateUnknownChannel(ulong channelId, ulong? guildId, ClientState state)
{
return SocketUnknownChannel.Create(this, state, channelId, guildId);
}

private async Task GuildAvailableAsync(SocketGuild guild)
{


+ 2
- 0
src/Discord.Net.WebSocket/Entities/Channels/SocketChannelHelper.cs View File

@@ -71,6 +71,7 @@ namespace Discord.WebSocket
case SocketDMChannel dmChannel: dmChannel.AddMessage(msg); break;
case SocketGroupChannel groupChannel: groupChannel.AddMessage(msg); break;
case SocketTextChannel textChannel: textChannel.AddMessage(msg); break;
case SocketUnknownChannel unknownChannel: unknownChannel.AddMessage(msg); break;
default: throw new NotSupportedException($"Unexpected {nameof(ISocketMessageChannel)} type.");
}
}
@@ -83,6 +84,7 @@ namespace Discord.WebSocket
case SocketDMChannel dmChannel: return dmChannel.RemoveMessage(id);
case SocketGroupChannel groupChannel: return groupChannel.RemoveMessage(id);
case SocketTextChannel textChannel: return textChannel.RemoveMessage(id);
case SocketUnknownChannel unknownChannel: return unknownChannel.RemoveMessage(id);
default: throw new NotSupportedException($"Unexpected {nameof(ISocketMessageChannel)} type.");
}
}


+ 222
- 0
src/Discord.Net.WebSocket/Entities/Channels/SocketUnknownChannel.cs View File

@@ -0,0 +1,222 @@
using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Discord.WebSocket
{
public class SocketUnknownChannel : SocketChannel, ISocketMessageChannel
{
public string Name => null;

public ulong? GuildId { get; private set; }

public IReadOnlyCollection<SocketMessage> CachedMessages => ImmutableArray.Create<SocketMessage>();

internal SocketUnknownChannel(DiscordSocketClient discord, ulong id)
: base(discord, id)
{
}
internal static SocketUnknownChannel Create(DiscordSocketClient discord, ClientState state, ulong channelId, ulong? guildId)
{
var entity = new SocketUnknownChannel(discord, channelId);
entity.Update(state, guildId);
return entity;
}
internal override void Update(ClientState state, API.Channel model)
{
}
internal void Update(ClientState state, ulong? guildId)
{
GuildId = guildId;
}

internal override SocketUser GetUserInternal(ulong id)
=> null;
internal override IReadOnlyCollection<SocketUser> GetUsersInternal()
=> ImmutableArray.Create<SocketUser>();
internal void AddMessage(SocketMessage msg)
{
}
internal SocketMessage RemoveMessage(ulong id)
=> null;

/// <summary>
/// Gets a message from this message channel.
/// </summary>
/// <remarks>
/// This method follows the same behavior as described in <see cref="IMessageChannel.GetMessageAsync"/>.
/// Please visit its documentation for more details on this method.
/// </remarks>
/// <param name="id">The snowflake identifier of the message.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents an asynchronous get operation for retrieving the message. The task result contains
/// the retrieved message; <c>null</c> if no message is found with the specified identifier.
/// </returns>
public async Task<IMessage> GetMessageAsync(ulong id, RequestOptions options = null)
=> await ChannelHelper.GetMessageAsync(this, Discord, id, options).ConfigureAwait(false);

/// <summary>
/// Gets the last N messages from this message channel.
/// </summary>
/// <remarks>
/// This method follows the same behavior as described in <see cref="IMessageChannel.GetMessagesAsync(int, CacheMode, RequestOptions)"/>.
/// Please visit its documentation for more details on this method.
/// </remarks>
/// <param name="limit">The numbers of message to be gotten from.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// Paged collection of messages.
/// </returns>
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> SocketChannelHelper.GetMessagesAsync(this, Discord, null, null, Direction.Before, limit, CacheMode.AllowDownload, options);
/// <summary>
/// Gets a collection of messages in this channel.
/// </summary>
/// <remarks>
/// This method follows the same behavior as described in <see cref="IMessageChannel.GetMessagesAsync(ulong, Direction, int, CacheMode, RequestOptions)"/>.
/// Please visit its documentation for more details on this method.
/// </remarks>
/// <param name="fromMessageId">The ID of the starting message to get the messages from.</param>
/// <param name="dir">The direction of the messages to be gotten from.</param>
/// <param name="limit">The numbers of message to be gotten from.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// Paged collection of messages.
/// </returns>
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> SocketChannelHelper.GetMessagesAsync(this, Discord, null, fromMessageId, dir, limit, CacheMode.AllowDownload, options);
/// <summary>
/// Gets a collection of messages in this channel.
/// </summary>
/// <remarks>
/// This method follows the same behavior as described in <see cref="IMessageChannel.GetMessagesAsync(IMessage, Direction, int, CacheMode, RequestOptions)"/>.
/// Please visit its documentation for more details on this method.
/// </remarks>
/// <param name="fromMessage">The starting message to get the messages from.</param>
/// <param name="dir">The direction of the messages to be gotten from.</param>
/// <param name="limit">The numbers of message to be gotten from.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// Paged collection of messages.
/// </returns>
public IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> SocketChannelHelper.GetMessagesAsync(this, Discord, null, fromMessage.Id, dir, limit, CacheMode.AllowDownload, options);

/// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, options);

/// <inheritdoc />
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, options, isSpoiler);

/// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, options, isSpoiler);

/// <inheritdoc />
public async Task<IUserMessage> ModifyMessageAsync(ulong messageId, Action<MessageProperties> func, RequestOptions options = null)
=> await ChannelHelper.ModifyMessageAsync(this, messageId, func, Discord, options).ConfigureAwait(false);

/// <inheritdoc />
public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
=> ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
/// <inheritdoc />
public Task DeleteMessageAsync(IMessage message, RequestOptions options = null)
=> ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options);

/// <inheritdoc />
public Task TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
/// <inheritdoc />
public IDisposable EnterTypingState(RequestOptions options = null)
=> ChannelHelper.EnterTypingState(this, Discord, options);

/// <inheritdoc />
public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null)
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, options);

/// <summary>
/// Gets a user in this channel.
/// </summary>
/// <param name="id">The snowflake identifier of the user.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <exception cref="InvalidOperationException">
/// Resolving permissions requires the parent guild to be downloaded.
/// </exception>
/// <returns>
/// A task representing the asynchronous get operation. The task result contains a guild user object that
/// represents the user; <c>null</c> if none is found.
/// </returns>
public Task<RestGuildUser> GetUserAsync(ulong id, RequestOptions options = null)
=> Task.FromResult<RestGuildUser>(null);

/// <summary>
/// Gets a collection of users that are able to view the channel.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <exception cref="InvalidOperationException">
/// Resolving permissions requires the parent guild to be downloaded.
/// </exception>
/// <returns>
/// A paged collection containing a collection of guild users that can access this channel. Flattening the
/// paginated response into a collection of users with
/// <see cref="AsyncEnumerableExtensions.FlattenAsync{T}"/> is required if you wish to access the users.
/// </returns>
public IAsyncEnumerable<IReadOnlyCollection<RestGuildUser>> GetUsersAsync(RequestOptions options = null)
=> AsyncEnumerable.Empty<IReadOnlyCollection<RestGuildUser>>();

/// <inheritdoc />
public SocketMessage GetCachedMessage(ulong id)
=> null;
/// <inheritdoc />
public IReadOnlyCollection<SocketMessage> GetCachedMessages(int limit = 100)
=> ImmutableArray.Create<SocketMessage>();
/// <inheritdoc />
public IReadOnlyCollection<SocketMessage> GetCachedMessages(ulong fromMessageId, Direction dir, int limit = 100)
=> ImmutableArray.Create<SocketMessage>();
/// <inheritdoc />
public IReadOnlyCollection<SocketMessage> GetCachedMessages(IMessage fromMessage, Direction dir, int limit = 100)
=> ImmutableArray.Create<SocketMessage>();

//IMessageChannel
/// <inheritdoc />
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return await GetMessageAsync(id, options).ConfigureAwait(false);
else
return GetCachedMessage(id);
}
/// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, RequestOptions options)
=> SocketChannelHelper.GetMessagesAsync(this, Discord, null, null, Direction.Before, limit, mode, options);
/// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options)
=> SocketChannelHelper.GetMessagesAsync(this, Discord, null, fromMessageId, dir, limit, mode, options);
/// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, Direction dir, int limit, CacheMode mode, RequestOptions options)
=> SocketChannelHelper.GetMessagesAsync(this, Discord, null, fromMessage.Id, dir, limit, mode, options);

/// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference).ConfigureAwait(false);
/// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference).ConfigureAwait(false);
/// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference).ConfigureAwait(false);

/// <inheritdoc />
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
}
}

Loading…
Cancel
Save