diff --git a/src/Discord.Net.Core/API/DiscordRestApiClient.cs b/src/Discord.Net.Core/API/DiscordRestApiClient.cs index d8f279132..fc62d3be0 100644 --- a/src/Discord.Net.Core/API/DiscordRestApiClient.cs +++ b/src/Discord.Net.Core/API/DiscordRestApiClient.cs @@ -38,6 +38,7 @@ namespace Discord.API public TokenType AuthTokenType { get; private set; } public User CurrentUser { get; private set; } public RequestQueue RequestQueue { get; private set; } + internal bool FetchCurrentUser { get; set; } public DiscordRestApiClient(RestClientProvider restClientProvider, string userAgent, JsonSerializer serializer = null, RequestQueue requestQueue = null) { @@ -45,6 +46,7 @@ namespace Discord.API _userAgent = userAgent; _serializer = serializer ?? new JsonSerializer { ContractResolver = new DiscordContractResolver() }; RequestQueue = requestQueue; + FetchCurrentUser = true; _stateLock = new SemaphoreSlim(1, 1); @@ -113,7 +115,8 @@ namespace Discord.API _authToken = token; _restClient.SetHeader("authorization", GetPrefixedToken(AuthTokenType, _authToken)); - CurrentUser = await GetMyUserAsync(new RequestOptions { IgnoreState = true }); + if (FetchCurrentUser) + CurrentUser = await GetMyUserAsync(new RequestOptions { IgnoreState = true }); LoginState = LoginState.LoggedIn; } diff --git a/src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs b/src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs index da6cce925..e8789976e 100644 --- a/src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs +++ b/src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs @@ -8,6 +8,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Text; @@ -67,13 +68,16 @@ namespace Discord.API public ConnectionState ConnectionState { get; private set; } - public DiscordRpcApiClient(string clientId, string userAgent, string origin, RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, JsonSerializer serializer = null, RequestQueue requestQueue = null) + public DiscordRpcApiClient(string clientId, string userAgent, string origin, RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, + JsonSerializer serializer = null, RequestQueue requestQueue = null) : base(restClientProvider, userAgent, serializer, requestQueue) { _connectionLock = new SemaphoreSlim(1, 1); _clientId = clientId; _origin = origin; + FetchCurrentUser = false; + _requestQueue = requestQueue ?? new RequestQueue(); _requests = new ConcurrentDictionary(); @@ -169,7 +173,7 @@ namespace Discord.API if (!success) throw new Exception("Unable to connect to the RPC server."); - + SetBaseUrl($"https://{uuid}.discordapp.io:{port}/"); ConnectionState = ConnectionState.Connected; } @@ -209,7 +213,6 @@ namespace Discord.API public async Task SendRpcAsync(string cmd, object payload, Optional evt = default(Optional), RequestOptions options = null) where TResponse : class { - options.IgnoreState = false; return await SendRpcAsyncInternal(cmd, payload, evt, options).ConfigureAwait(false); } private async Task SendRpcAsyncInternal(string cmd, object payload, Optional evt, RequestOptions options) @@ -246,7 +249,7 @@ namespace Discord.API options.IgnoreState = true; return await SendRpcAsync("AUTHENTICATE", msg, options: options).ConfigureAwait(false); } - public async Task SendAuthorizeAsync(string[] scopes, string rpcToken = null, RequestOptions options = null) + public async Task SendAuthorizeAsync(IReadOnlyCollection scopes, string rpcToken = null, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var msg = new AuthorizeParams diff --git a/src/Discord.Net.Rpc/API/Rpc/AuthorizeParams.cs b/src/Discord.Net.Rpc/API/Rpc/AuthorizeParams.cs index 606e96f9a..367aafd41 100644 --- a/src/Discord.Net.Rpc/API/Rpc/AuthorizeParams.cs +++ b/src/Discord.Net.Rpc/API/Rpc/AuthorizeParams.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 using Newtonsoft.Json; +using System.Collections.Generic; namespace Discord.API.Rpc { @@ -8,7 +9,7 @@ namespace Discord.API.Rpc [JsonProperty("client_id")] public string ClientId { get; set; } [JsonProperty("scopes")] - public string[] Scopes { get; set; } + public IReadOnlyCollection Scopes { get; set; } [JsonProperty("rpc_token")] public Optional RpcToken { get; set; } } diff --git a/src/Discord.Net.Rpc/DiscordRpcClient.Events.cs b/src/Discord.Net.Rpc/DiscordRpcClient.Events.cs index 25989d01a..a746c180c 100644 --- a/src/Discord.Net.Rpc/DiscordRpcClient.Events.cs +++ b/src/Discord.Net.Rpc/DiscordRpcClient.Events.cs @@ -42,18 +42,18 @@ namespace Discord.Rpc private readonly AsyncEvent> _voiceStateUpdatedEvent = new AsyncEvent>(); //Messages - public event Func MessageReceived + public event Func MessageReceived { add { _messageReceivedEvent.Add(value); } remove { _messageReceivedEvent.Remove(value); } } - private readonly AsyncEvent> _messageReceivedEvent = new AsyncEvent>(); - public event Func MessageUpdated + private readonly AsyncEvent> _messageReceivedEvent = new AsyncEvent>(); + public event Func MessageUpdated { add { _messageUpdatedEvent.Add(value); } remove { _messageUpdatedEvent.Remove(value); } } - private readonly AsyncEvent> _messageUpdatedEvent = new AsyncEvent>(); + private readonly AsyncEvent> _messageUpdatedEvent = new AsyncEvent>(); public event Func MessageDeleted { add { _messageDeletedEvent.Add(value); } diff --git a/src/Discord.Net.Rpc/DiscordRpcClient.cs b/src/Discord.Net.Rpc/DiscordRpcClient.cs index eedc98718..efbfb7126 100644 --- a/src/Discord.Net.Rpc/DiscordRpcClient.cs +++ b/src/Discord.Net.Rpc/DiscordRpcClient.cs @@ -6,6 +6,8 @@ using Discord.Rest; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; +using System.Collections.Generic; +using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; @@ -22,11 +24,15 @@ namespace Discord.Rpc private bool _canReconnect; public ConnectionState ConnectionState { get; private set; } + public IReadOnlyCollection Scopes { get; private set; } + public DateTimeOffset TokenExpiresAt { get; private set; } //From DiscordRpcConfig internal int ConnectionTimeout { get; private set; } public new API.DiscordRpcApiClient ApiClient => base.ApiClient as API.DiscordRpcApiClient; + public new RestSelfUser CurrentUser { get { return base.CurrentUser as RestSelfUser; } private set { base.CurrentUser = value; } } + public RestApplication CurrentApplication { get; private set; } /// Creates a new RPC discord client. public DiscordRpcClient(string clientId, string origin) @@ -58,6 +64,7 @@ namespace Discord.Rpc await _rpcLogger.WarningAsync($"Connection Closed").ConfigureAwait(false); }; } + private static API.DiscordRpcApiClient CreateApiClient(string clientId, string origin, DiscordRpcConfig config) => new API.DiscordRpcApiClient(clientId, DiscordRestConfig.UserAgent, origin, config.RestClientProvider, config.WebSocketProvider, requestQueue: new RequestQueue()); @@ -286,19 +293,21 @@ namespace Discord.Rpc { await _rpcLogger.DebugAsync("Received Dispatch (READY)").ConfigureAwait(false); var data = (payload.Value as JToken).ToObject(_serializer); - var cancelToken = _cancelToken; + + RequestOptions options = new RequestOptions + { + //CancellationToken = _cancelToken //TODO: Implement + }; var _ = Task.Run(async () => { try { - RequestOptions options = new RequestOptions - { - //CancellationToken = cancelToken //TODO: Implement - }; - - if (LoginState != LoginState.LoggedOut) - await ApiClient.SendAuthenticateAsync(options).ConfigureAwait(false); //Has bearer + var response = await ApiClient.SendAuthenticateAsync(options).ConfigureAwait(false); + CurrentUser = RestSelfUser.Create(this, response.User); + CurrentApplication = RestApplication.Create(this, response.Application); + Scopes = response.Scopes; + TokenExpiresAt = response.Expires; var __ = _connectTask.TrySetResultAsync(true); //Signal the .Connect() call to complete await _rpcLogger.InfoAsync("Ready").ConfigureAwait(false); @@ -361,20 +370,20 @@ namespace Discord.Rpc //Messages case "MESSAGE_CREATE": { - /*await _rpcLogger.DebugAsync("Received Dispatch (MESSAGE_CREATE)").ConfigureAwait(false); + await _rpcLogger.DebugAsync("Received Dispatch (MESSAGE_CREATE)").ConfigureAwait(false); var data = (payload.Value as JToken).ToObject(_serializer); - var msg = new RpcMessage(this, data.Message); + var msg = RpcMessage.Create(this, data.ChannelId, data.Message); - await _messageReceivedEvent.InvokeAsync(data.ChannelId, msg).ConfigureAwait(false);*/ + await _messageReceivedEvent.InvokeAsync(msg).ConfigureAwait(false); } break; case "MESSAGE_UPDATE": { - /*await _rpcLogger.DebugAsync("Received Dispatch (MESSAGE_UPDATE)").ConfigureAwait(false); + await _rpcLogger.DebugAsync("Received Dispatch (MESSAGE_UPDATE)").ConfigureAwait(false); var data = (payload.Value as JToken).ToObject(_serializer); - var msg = new RpcMessage(this, data.Message); + var msg = RpcMessage.Create(this, data.ChannelId, data.Message); - await _messageUpdatedEvent.InvokeAsync(data.ChannelId, msg).ConfigureAwait(false);*/ + await _messageUpdatedEvent.InvokeAsync(msg).ConfigureAwait(false); } break; case "MESSAGE_DELETE": diff --git a/src/Discord.Net.Rpc/DiscordRpcConfig.cs b/src/Discord.Net.Rpc/DiscordRpcConfig.cs index 8ca1ae32e..d1e69376c 100644 --- a/src/Discord.Net.Rpc/DiscordRpcConfig.cs +++ b/src/Discord.Net.Rpc/DiscordRpcConfig.cs @@ -9,7 +9,7 @@ namespace Discord.Rpc public const int PortRangeStart = 6463; public const int PortRangeEnd = 6472; - + /// Gets or sets the time, in milliseconds, to wait for a connection to complete before aborting. public int ConnectionTimeout { get; set; } = 30000;