You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

RestDMChannel.cs 12 kB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Immutable;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Threading.Tasks;
  8. using Model = Discord.API.Channel;
  9. namespace Discord.Rest
  10. {
  11. /// <summary>
  12. /// Represents a REST-based direct-message channel.
  13. /// </summary>
  14. [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
  15. public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel
  16. {
  17. /// <summary>
  18. /// Gets the current logged-in user.
  19. /// </summary>
  20. public RestUser CurrentUser { get; }
  21. /// <summary>
  22. /// Gets the recipient of the channel.
  23. /// </summary>
  24. public RestUser Recipient { get; }
  25. /// <summary>
  26. /// Gets a collection that is the current logged-in user and the recipient.
  27. /// </summary>
  28. public IReadOnlyCollection<RestUser> Users => ImmutableArray.Create(CurrentUser, Recipient);
  29. internal RestDMChannel(BaseDiscordClient discord, ulong id, ulong recipientId)
  30. : base(discord, id)
  31. {
  32. Recipient = new RestUser(Discord, recipientId);
  33. CurrentUser = new RestUser(Discord, discord.CurrentUser.Id);
  34. }
  35. internal new static RestDMChannel Create(BaseDiscordClient discord, Model model)
  36. {
  37. var entity = new RestDMChannel(discord, model.Id, model.Recipients.Value[0].Id);
  38. entity.Update(model);
  39. return entity;
  40. }
  41. internal override void Update(Model model)
  42. {
  43. Recipient.Update(model.Recipients.Value[0]);
  44. }
  45. /// <inheritdoc />
  46. public override async Task UpdateAsync(RequestOptions options = null)
  47. {
  48. var model = await Discord.ApiClient.GetChannelAsync(Id, options).ConfigureAwait(false);
  49. Update(model);
  50. }
  51. /// <inheritdoc />
  52. public Task CloseAsync(RequestOptions options = null)
  53. => ChannelHelper.DeleteAsync(this, Discord, options);
  54. /// <summary>
  55. /// Gets a user in this channel from the provided <paramref name="id"/>.
  56. /// </summary>
  57. /// <param name="id">The snowflake identifier of the user.</param>
  58. /// <returns>
  59. /// A <see cref="RestUser"/> object that is a recipient of this channel; otherwise <c>null</c>.
  60. /// </returns>
  61. public RestUser GetUser(ulong id)
  62. {
  63. if (id == Recipient.Id)
  64. return Recipient;
  65. else if (id == Discord.CurrentUser.Id)
  66. return CurrentUser;
  67. else
  68. return null;
  69. }
  70. /// <inheritdoc />
  71. public Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null)
  72. => ChannelHelper.GetMessageAsync(this, Discord, id, options);
  73. /// <inheritdoc />
  74. public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
  75. => ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, options);
  76. /// <inheritdoc />
  77. public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
  78. => ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, options);
  79. /// <inheritdoc />
  80. public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
  81. => ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, options);
  82. /// <inheritdoc />
  83. public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null)
  84. => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options);
  85. /// <inheritdoc />
  86. /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
  87. public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null)
  88. => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
  89. /// <inheritdoc />
  90. /// <exception cref="ArgumentException">
  91. /// <paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more
  92. /// invalid characters as defined by <see cref="System.IO.Path.GetInvalidPathChars"/>.
  93. /// </exception>
  94. /// <exception cref="ArgumentNullException">
  95. /// <paramref name="filePath" /> is <c>null</c>.
  96. /// </exception>
  97. /// <exception cref="PathTooLongException">
  98. /// The specified path, file name, or both exceed the system-defined maximum length. For example, on
  99. /// Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260
  100. /// characters.
  101. /// </exception>
  102. /// <exception cref="DirectoryNotFoundException">
  103. /// The specified path is invalid, (for example, it is on an unmapped drive).
  104. /// </exception>
  105. /// <exception cref="UnauthorizedAccessException">
  106. /// <paramref name="filePath" /> specified a directory.-or- The caller does not have the required permission.
  107. /// </exception>
  108. /// <exception cref="FileNotFoundException">
  109. /// The file specified in <paramref name="filePath" /> was not found.
  110. /// </exception>
  111. /// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception>
  112. /// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
  113. /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
  114. public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
  115. => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
  116. /// <inheritdoc />
  117. /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
  118. public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
  119. => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
  120. /// <inheritdoc />
  121. public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
  122. => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
  123. /// <inheritdoc />
  124. public Task DeleteMessageAsync(IMessage message, RequestOptions options = null)
  125. => ChannelHelper.DeleteMessageAsync(this, message.Id, Discord, options);
  126. /// <inheritdoc />
  127. public Task TriggerTypingAsync(RequestOptions options = null)
  128. => ChannelHelper.TriggerTypingAsync(this, Discord, options);
  129. /// <inheritdoc />
  130. public IDisposable EnterTypingState(RequestOptions options = null)
  131. => ChannelHelper.EnterTypingState(this, Discord, options);
  132. /// <summary>
  133. /// Gets a string that represents the Username#Discriminator of the recipient.
  134. /// </summary>
  135. /// <returns>
  136. /// A string that resolves to the Recipient of this channel.
  137. /// </returns>
  138. public override string ToString() => $"@{Recipient}";
  139. private string DebuggerDisplay => $"@{Recipient} ({Id}, DM)";
  140. //IDMChannel
  141. /// <inheritdoc />
  142. IUser IDMChannel.Recipient => Recipient;
  143. //IRestPrivateChannel
  144. /// <inheritdoc />
  145. IReadOnlyCollection<RestUser> IRestPrivateChannel.Recipients => ImmutableArray.Create(Recipient);
  146. //IPrivateChannel
  147. /// <inheritdoc />
  148. IReadOnlyCollection<IUser> IPrivateChannel.Recipients => ImmutableArray.Create<IUser>(Recipient);
  149. //IMessageChannel
  150. /// <inheritdoc />
  151. async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
  152. {
  153. if (mode == CacheMode.AllowDownload)
  154. return await GetMessageAsync(id, options).ConfigureAwait(false);
  155. else
  156. return null;
  157. }
  158. /// <inheritdoc />
  159. IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, RequestOptions options)
  160. {
  161. if (mode == CacheMode.AllowDownload)
  162. return GetMessagesAsync(limit, options);
  163. else
  164. return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
  165. }
  166. /// <inheritdoc />
  167. IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options)
  168. {
  169. if (mode == CacheMode.AllowDownload)
  170. return GetMessagesAsync(fromMessageId, dir, limit, options);
  171. else
  172. return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
  173. }
  174. /// <inheritdoc />
  175. IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, Direction dir, int limit, CacheMode mode, RequestOptions options)
  176. {
  177. if (mode == CacheMode.AllowDownload)
  178. return GetMessagesAsync(fromMessage, dir, limit, options);
  179. else
  180. return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
  181. }
  182. /// <inheritdoc />
  183. async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
  184. => await GetPinnedMessagesAsync(options).ConfigureAwait(false);
  185. /// <inheritdoc />
  186. async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
  187. => await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
  188. /// <inheritdoc />
  189. async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
  190. => await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
  191. /// <inheritdoc />
  192. async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
  193. => await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
  194. //IChannel
  195. /// <inheritdoc />
  196. string IChannel.Name => $"@{Recipient}";
  197. /// <inheritdoc />
  198. Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
  199. => Task.FromResult<IUser>(GetUser(id));
  200. /// <inheritdoc />
  201. IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
  202. => ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable();
  203. }
  204. }