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.

BaseSocketClient.cs 13 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
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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using System.Threading.Tasks;
  4. using Discord.API;
  5. using Discord.Rest;
  6. namespace Discord.WebSocket
  7. {
  8. public abstract partial class BaseSocketClient : BaseDiscordClient, IDiscordClient
  9. {
  10. protected readonly DiscordSocketConfig BaseConfig;
  11. /// <summary>
  12. /// Gets the estimated round-trip latency, in milliseconds, to the gateway server.
  13. /// </summary>
  14. public abstract int Latency { get; protected set; }
  15. /// <summary>
  16. /// Gets the status for the logged-in user.
  17. /// </summary>
  18. public abstract UserStatus Status { get; protected set; }
  19. /// <summary>
  20. /// Gets the activity for the logged-in user.
  21. /// </summary>
  22. public abstract IActivity Activity { get; protected set; }
  23. internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient;
  24. /// <summary>
  25. /// Gets the current logged-in user.
  26. /// </summary>
  27. public new SocketSelfUser CurrentUser { get => base.CurrentUser as SocketSelfUser; protected set => base.CurrentUser = value; }
  28. /// <summary>
  29. /// Gets a collection of guilds that the logged-in user is currently in.
  30. /// </summary>
  31. public abstract IReadOnlyCollection<SocketGuild> Guilds { get; }
  32. /// <summary>
  33. /// Gets a collection of private channels that are currently open for the logged-in user.
  34. /// </summary>
  35. public abstract IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels { get; }
  36. /// <summary>
  37. /// Gets a collection of available voice regions for the logged-in user.
  38. /// </summary>
  39. public abstract IReadOnlyCollection<RestVoiceRegion> VoiceRegions { get; }
  40. internal BaseSocketClient(DiscordSocketConfig config, DiscordRestApiClient client)
  41. : base(config, client) => BaseConfig = config;
  42. private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
  43. => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent);
  44. /// <summary>
  45. /// Gets a Discord application information for the logged-in user.
  46. /// </summary>
  47. /// <remarks>
  48. /// This method reflects your application information you submitted when creating a Discord application via
  49. /// the Developer Portal.
  50. /// </remarks>
  51. /// <param name="options">The options to be used when sending the request.</param>
  52. /// <returns>
  53. /// An awaitable <see cref="Task"/> containing the application information.
  54. /// </returns>
  55. public abstract Task<RestApplication> GetApplicationInfoAsync(RequestOptions options = null);
  56. /// <summary>
  57. /// Gets a user.
  58. /// </summary>
  59. /// <param name="id">The user snowflake ID.</param>
  60. /// <remarks>
  61. /// This method gets the user present in the WebSocket cache with the given condition.
  62. /// <note>
  63. /// Sometimes a user may return <c>null</c> due to Discord not sending offline users in large
  64. /// guilds (i.e. guild with 100+ members) actively. To download users on startup, consider enabling
  65. /// <see cref="DiscordSocketConfig.AlwaysDownloadUsers"/>.
  66. /// </note>
  67. /// <note>
  68. /// This method does not attempt to fetch users that the logged-in user does not have access to (i.e.
  69. /// users who don't share mutual guild(s) with the current user).
  70. /// </note>
  71. /// </remarks>
  72. /// <returns>
  73. /// A generic WebSocket-based user; <c>null</c> when the user cannot be found.
  74. /// </returns>
  75. public abstract SocketUser GetUser(ulong id);
  76. /// <summary>
  77. /// Gets a user.
  78. /// </summary>
  79. /// <param name="username">The name of the user.</param>
  80. /// <param name="discriminator">The discriminator value of the user.</param>
  81. /// <remarks>
  82. /// This method gets the user present in the WebSocket cache with the given condition.
  83. /// <note>
  84. /// Sometimes a user may return <c>null</c> due to Discord not sending offline users in large
  85. /// guilds (i.e. guild with 100+ members) actively. To download users on startup, consider enabling
  86. /// <see cref="DiscordSocketConfig.AlwaysDownloadUsers"/>.
  87. /// </note>
  88. /// <note>
  89. /// This method does not attempt to fetch users that the logged-in user does not have access to (i.e.
  90. /// users who don't share mutual guild(s) with the current user).
  91. /// </note>
  92. /// </remarks>
  93. /// <returns>
  94. /// A generic WebSocket-based user; <c>null</c> when the user cannot be found.
  95. /// </returns>
  96. public abstract SocketUser GetUser(string username, string discriminator);
  97. /// <summary>
  98. /// Gets a channel.
  99. /// </summary>
  100. /// <param name="id">The channel snowflake ID.</param>
  101. /// <returns>
  102. /// A generic WebSocket-based channel object (voice, text, category, etc.); <c>null</c> when the
  103. /// channel cannot be found.
  104. /// </returns>
  105. public abstract SocketChannel GetChannel(ulong id);
  106. /// <summary>
  107. /// Gets a guild.
  108. /// </summary>
  109. /// <param name="id">The guild snowflake ID.</param>
  110. /// <returns>
  111. /// A WebSocket-based guild; <c>null</c> when the guild cannot be found.
  112. /// </returns>
  113. public abstract SocketGuild GetGuild(ulong id);
  114. /// <summary>
  115. /// Gets a voice region.
  116. /// </summary>
  117. /// <param name="id">The unique identifier of the voice region.</param>
  118. /// <returns>
  119. /// A REST-based voice region; <c>null</c> if none can be found.
  120. /// </returns>
  121. public abstract RestVoiceRegion GetVoiceRegion(string id);
  122. /// <inheritdoc />
  123. public abstract Task StartAsync();
  124. /// <inheritdoc />
  125. public abstract Task StopAsync();
  126. /// <summary>
  127. /// Sets the current status of the logged-in user (e.g. Online, Do not Disturb).
  128. /// </summary>
  129. /// <param name="status">The new status to be set.</param>
  130. /// <returns>
  131. /// An awaitable <see cref="Task"/>.
  132. /// </returns>
  133. public abstract Task SetStatusAsync(UserStatus status);
  134. /// <summary>
  135. /// Sets the game of the logged-in user.
  136. /// </summary>
  137. /// <param name="name">The name of the game.</param>
  138. /// <param name="streamUrl">If streaming, the URL of the stream. Must be a valid Twitch URL.</param>
  139. /// <param name="type">The type of the game.</param>
  140. /// <returns>
  141. /// An awaitable <see cref="Task"/>.
  142. /// </returns>
  143. public abstract Task SetGameAsync(string name, string streamUrl = null, ActivityType type = ActivityType.Playing);
  144. /// <summary>
  145. /// Sets the <paramref name="activity"/> of the logged-in user.
  146. /// </summary>
  147. /// <remarks>
  148. /// This method sets the <paramref name="activity"/> of the user.
  149. /// <note type="note">
  150. /// Discord will only accept setting of name and the type of activity.
  151. /// </note>
  152. /// <note type="warning">
  153. /// Rich Presence cannot be set via this method or client. Rich Presence is strictly limited to RPC
  154. /// clients only.
  155. /// </note>
  156. /// </remarks>
  157. /// <param name="activity">The activty to be set.</param>
  158. /// <returns>
  159. /// An awaitable <see cref="Task"/>.
  160. /// </returns>
  161. public abstract Task SetActivityAsync(IActivity activity);
  162. /// <summary>
  163. /// Attempts to download users into the user cache for the selected guilds.
  164. /// </summary>
  165. /// <param name="guilds">The guilds to download the members from.</param>
  166. /// <returns>
  167. /// An awaitable <see cref="Task"/>.
  168. /// </returns>
  169. public abstract Task DownloadUsersAsync(IEnumerable<IGuild> guilds);
  170. /// <summary>
  171. /// Creates a guild for the logged-in user who is in less than 10 active guilds.
  172. /// </summary>
  173. /// <remarks>
  174. /// This method creates a new guild on behalf of the logged-in user.
  175. /// <note type="warning">
  176. /// Due to Discord's limitation, this method will only work for users that are in less than 10 guilds.
  177. /// </note>
  178. /// </remarks>
  179. /// <param name="name">The name of the new guild.</param>
  180. /// <param name="region">The voice region to create the guild with.</param>
  181. /// <param name="jpegIcon">The icon of the guild.</param>
  182. /// <param name="options">The options to be used when sending the request.</param>
  183. /// <returns>
  184. /// An awaitable <see cref="Task"/> containing the newly created guild.
  185. /// </returns>
  186. public Task<RestGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null, RequestOptions options = null)
  187. => ClientHelper.CreateGuildAsync(this, name, region, jpegIcon, options ?? RequestOptions.Default);
  188. /// <summary>
  189. /// Gets the connections that the logged-in user has set up.
  190. /// </summary>
  191. /// <param name="options">The options to be used when sending the request.</param>
  192. /// <returns>
  193. /// An awaitable <see cref="Task"/> containing a collection of connections.
  194. /// </returns>
  195. public Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(RequestOptions options = null)
  196. => ClientHelper.GetConnectionsAsync(this, options ?? RequestOptions.Default);
  197. /// <summary>
  198. /// Gets an invite with the provided invite identifier.
  199. /// </summary>
  200. /// <param name="inviteId">The invitation identifier.</param>
  201. /// <param name="options">The options to be used when sending the request.</param>
  202. /// <returns>
  203. /// An awaitable <see cref="Task"/> containing the invite information.
  204. /// </returns>
  205. public Task<RestInviteMetadata> GetInviteAsync(string inviteId, bool withCount = false, RequestOptions options = null)
  206. => ClientHelper.GetInviteAsync(this, inviteId, withCount, options ?? RequestOptions.Default);
  207. // IDiscordClient
  208. /// <inheritdoc />
  209. async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options)
  210. => await GetApplicationInfoAsync(options).ConfigureAwait(false);
  211. /// <inheritdoc />
  212. Task<IChannel> IDiscordClient.GetChannelAsync(ulong id, CacheMode mode, RequestOptions options)
  213. => Task.FromResult<IChannel>(GetChannel(id));
  214. /// <inheritdoc />
  215. Task<IReadOnlyCollection<IPrivateChannel>> IDiscordClient.GetPrivateChannelsAsync(CacheMode mode, RequestOptions options)
  216. => Task.FromResult<IReadOnlyCollection<IPrivateChannel>>(PrivateChannels);
  217. /// <inheritdoc />
  218. async Task<IReadOnlyCollection<IConnection>> IDiscordClient.GetConnectionsAsync(RequestOptions options)
  219. => await GetConnectionsAsync(options).ConfigureAwait(false);
  220. /// <inheritdoc />
  221. async Task<IInvite> IDiscordClient.GetInviteAsync(string inviteId, bool withCount, RequestOptions options)
  222. => await GetInviteAsync(inviteId, withCount, options).ConfigureAwait(false);
  223. /// <inheritdoc />
  224. Task<IGuild> IDiscordClient.GetGuildAsync(ulong id, CacheMode mode, RequestOptions options)
  225. => Task.FromResult<IGuild>(GetGuild(id));
  226. /// <inheritdoc />
  227. Task<IReadOnlyCollection<IGuild>> IDiscordClient.GetGuildsAsync(CacheMode mode, RequestOptions options)
  228. => Task.FromResult<IReadOnlyCollection<IGuild>>(Guilds);
  229. /// <inheritdoc />
  230. async Task<IGuild> IDiscordClient.CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon, RequestOptions options)
  231. => await CreateGuildAsync(name, region, jpegIcon, options).ConfigureAwait(false);
  232. /// <inheritdoc />
  233. Task<IUser> IDiscordClient.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
  234. => Task.FromResult<IUser>(GetUser(id));
  235. /// <inheritdoc />
  236. Task<IUser> IDiscordClient.GetUserAsync(string username, string discriminator, RequestOptions options)
  237. => Task.FromResult<IUser>(GetUser(username, discriminator));
  238. /// <inheritdoc />
  239. Task<IVoiceRegion> IDiscordClient.GetVoiceRegionAsync(string id, RequestOptions options)
  240. => Task.FromResult<IVoiceRegion>(GetVoiceRegion(id));
  241. /// <inheritdoc />
  242. Task<IReadOnlyCollection<IVoiceRegion>> IDiscordClient.GetVoiceRegionsAsync(RequestOptions options)
  243. => Task.FromResult<IReadOnlyCollection<IVoiceRegion>>(VoiceRegions);
  244. }
  245. }