diff --git a/src/Discord.Net.Rest/BaseDiscordClient.cs b/src/Discord.Net.Rest/BaseDiscordClient.cs
index fc938d04d..1837e38c0 100644
--- a/src/Discord.Net.Rest/BaseDiscordClient.cs
+++ b/src/Discord.Net.Rest/BaseDiscordClient.cs
@@ -65,7 +65,7 @@ namespace Discord.Rest
}
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)
{
@@ -118,7 +118,7 @@ namespace Discord.Rest
}
finally { _stateLock.Release(); }
}
- private async Task LogoutInternalAsync()
+ internal virtual async Task LogoutInternalAsync()
{
if (LoginState == LoginState.LoggedOut) return;
LoginState = LoginState.LoggingOut;
diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs
index f96d5dd0b..29bf89c50 100644
--- a/src/Discord.Net.Rest/DiscordRestClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestClient.cs
@@ -24,6 +24,8 @@ namespace Discord.Rest
///
/// The configuration to be used with the client.
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);
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index 1e431ec92..196aedf47 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -42,9 +42,10 @@ namespace Discord.WebSocket
private int _nextAudioId;
private DateTimeOffset? _statusSince;
private RestApplication _applicationInfo;
-
private bool _isDisposed;
+ /// Provides access to a REST-only client with a shared state from this client.
+ public DiscordSocketRestClient Rest { get; }
/// Gets the shard of of this client.
public int ShardId { get; }
/// Gets the current connection state of this client.
@@ -128,6 +129,7 @@ namespace Discord.WebSocket
AlwaysDownloadUsers = config.AlwaysDownloadUsers;
HandlerTimeout = config.HandlerTimeout;
State = new ClientState(0, 0);
+ Rest = new DiscordSocketRestClient(config, ApiClient);
_heartbeatTimes = new ConcurrentQueue();
_stateLock = new SemaphoreSlim(1, 1);
diff --git a/src/Discord.Net.WebSocket/DiscordSocketRestClient.cs b/src/Discord.Net.WebSocket/DiscordSocketRestClient.cs
new file mode 100644
index 000000000..5107629a8
--- /dev/null
+++ b/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.");
+ }
+}