Skip to content

Commit

Permalink
feature: add DiscordSocketRestClient (#1198)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
foxbot committed Dec 2, 2018
1 parent 6d3d906 commit 65afd37
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/Discord.Net.Rest/BaseDiscordClient.cs
Expand Up @@ -65,7 +65,7 @@ public async Task LoginAsync(TokenType tokenType, string token, bool validateTok
}
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)
{
Expand Down Expand Up @@ -118,7 +118,7 @@ public async Task LogoutAsync()
}
finally { _stateLock.Release(); }
}
private async Task LogoutInternalAsync()
internal virtual async Task LogoutInternalAsync()
{
if (LoginState == LoginState.LoggedOut) return;
LoginState = LoginState.LoggingOut;
Expand Down
2 changes: 2 additions & 0 deletions src/Discord.Net.Rest/DiscordRestClient.cs
Expand Up @@ -24,6 +24,8 @@ public class DiscordRestClient : BaseDiscordClient, IDiscordClient
/// </summary>
/// <param name="config">The configuration to be used with the client.</param>
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)
=> new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent);
Expand Down
4 changes: 3 additions & 1 deletion src/Discord.Net.WebSocket/DiscordSocketClient.cs
Expand Up @@ -42,9 +42,10 @@ public partial class DiscordSocketClient : BaseSocketClient, IDiscordClient
private int _nextAudioId;
private DateTimeOffset? _statusSince;
private RestApplication _applicationInfo;

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>
public int ShardId { get; }
/// <summary> Gets the current connection state of this client. </summary>
Expand Down Expand Up @@ -128,6 +129,7 @@ private DiscordSocketClient(DiscordSocketConfig config, API.DiscordSocketApiClie
AlwaysDownloadUsers = config.AlwaysDownloadUsers;
HandlerTimeout = config.HandlerTimeout;
State = new ClientState(0, 0);
Rest = new DiscordSocketRestClient(config, ApiClient);
_heartbeatTimes = new ConcurrentQueue<long>();

_stateLock = new SemaphoreSlim(1, 1);
Expand Down
20 changes: 20 additions & 0 deletions src/Discord.Net.WebSocket/DiscordSocketRestClient.cs
@@ -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.");
}
}

0 comments on commit 65afd37

Please sign in to comment.