feature: add DiscordSocketRestClient (#1198)
* feature: add DiscordSocketRestClient this resolves #803. Users can access a DiscordSocketRestClient from the new `DiscordSocketClient.Rest` property. DiscordSocketRestClient is a wrapper over DiscordRestClient with certain state-modifying methods, such as Login/Logout disabled, to prevent users from breaking the client state. DiscordSocketRestClient uses the same API client as the DiscordSocketClient, allowing for shared ratelimiting - meaning users can now force HTTP requests without needing to wory about running into 429s. * fix: disallow users from bypassing shadowed login
This commit is contained in:
@@ -65,7 +65,7 @@ namespace Discord.Rest
|
|||||||
}
|
}
|
||||||
finally { _stateLock.Release(); }
|
finally { _stateLock.Release(); }
|
||||||
}
|
}
|
||||||
private async Task LoginInternalAsync(TokenType tokenType, string token, bool validateToken)
|
internal virtual async Task LoginInternalAsync(TokenType tokenType, string token, bool validateToken)
|
||||||
{
|
{
|
||||||
if (_isFirstLogin)
|
if (_isFirstLogin)
|
||||||
{
|
{
|
||||||
@@ -118,7 +118,7 @@ namespace Discord.Rest
|
|||||||
}
|
}
|
||||||
finally { _stateLock.Release(); }
|
finally { _stateLock.Release(); }
|
||||||
}
|
}
|
||||||
private async Task LogoutInternalAsync()
|
internal virtual async Task LogoutInternalAsync()
|
||||||
{
|
{
|
||||||
if (LoginState == LoginState.LoggedOut) return;
|
if (LoginState == LoginState.LoggedOut) return;
|
||||||
LoginState = LoginState.LoggingOut;
|
LoginState = LoginState.LoggingOut;
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace Discord.Rest
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config">The configuration to be used with the client.</param>
|
/// <param name="config">The configuration to be used with the client.</param>
|
||||||
public DiscordRestClient(DiscordRestConfig config) : base(config, CreateApiClient(config)) { }
|
public DiscordRestClient(DiscordRestConfig config) : base(config, CreateApiClient(config)) { }
|
||||||
|
// used for socket client rest access
|
||||||
|
internal DiscordRestClient(DiscordRestConfig config, API.DiscordRestApiClient api) : base(config, api) { }
|
||||||
|
|
||||||
private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config)
|
private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config)
|
||||||
=> new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent);
|
=> new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent);
|
||||||
|
|||||||
@@ -42,9 +42,10 @@ namespace Discord.WebSocket
|
|||||||
private int _nextAudioId;
|
private int _nextAudioId;
|
||||||
private DateTimeOffset? _statusSince;
|
private DateTimeOffset? _statusSince;
|
||||||
private RestApplication _applicationInfo;
|
private RestApplication _applicationInfo;
|
||||||
|
|
||||||
private bool _isDisposed;
|
private bool _isDisposed;
|
||||||
|
|
||||||
|
/// <summary> Provides access to a REST-only client with a shared state from this client. </summary>
|
||||||
|
public DiscordSocketRestClient Rest { get; }
|
||||||
/// <summary> Gets the shard of of this client. </summary>
|
/// <summary> Gets the shard of of this client. </summary>
|
||||||
public int ShardId { get; }
|
public int ShardId { get; }
|
||||||
/// <summary> Gets the current connection state of this client. </summary>
|
/// <summary> Gets the current connection state of this client. </summary>
|
||||||
@@ -128,6 +129,7 @@ namespace Discord.WebSocket
|
|||||||
AlwaysDownloadUsers = config.AlwaysDownloadUsers;
|
AlwaysDownloadUsers = config.AlwaysDownloadUsers;
|
||||||
HandlerTimeout = config.HandlerTimeout;
|
HandlerTimeout = config.HandlerTimeout;
|
||||||
State = new ClientState(0, 0);
|
State = new ClientState(0, 0);
|
||||||
|
Rest = new DiscordSocketRestClient(config, ApiClient);
|
||||||
_heartbeatTimes = new ConcurrentQueue<long>();
|
_heartbeatTimes = new ConcurrentQueue<long>();
|
||||||
|
|
||||||
_stateLock = new SemaphoreSlim(1, 1);
|
_stateLock = new SemaphoreSlim(1, 1);
|
||||||
|
|||||||
20
src/Discord.Net.WebSocket/DiscordSocketRestClient.cs
Normal file
20
src/Discord.Net.WebSocket/DiscordSocketRestClient.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Discord.Rest;
|
||||||
|
|
||||||
|
namespace Discord.WebSocket
|
||||||
|
{
|
||||||
|
public class DiscordSocketRestClient : DiscordRestClient
|
||||||
|
{
|
||||||
|
internal DiscordSocketRestClient(DiscordRestConfig config, API.DiscordRestApiClient api) : base(config, api) { }
|
||||||
|
|
||||||
|
public new Task LoginAsync(TokenType tokenType, string token, bool validateToken = true)
|
||||||
|
=> throw new NotSupportedException("The Socket REST wrapper cannot be used to log in or out.");
|
||||||
|
internal override Task LoginInternalAsync(TokenType tokenType, string token, bool validateToken)
|
||||||
|
=> throw new NotSupportedException("The Socket REST wrapper cannot be used to log in or out.");
|
||||||
|
public new Task LogoutAsync()
|
||||||
|
=> throw new NotSupportedException("The Socket REST wrapper cannot be used to log in or out.");
|
||||||
|
internal override Task LogoutInternalAsync()
|
||||||
|
=> throw new NotSupportedException("The Socket REST wrapper cannot be used to log in or out.");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user