diff --git a/src/Discord.Net.WebSocket/API/Gateway/IdentifyParams.cs b/src/Discord.Net.WebSocket/API/Gateway/IdentifyParams.cs index 1e0bf71c2..fb663594a 100644 --- a/src/Discord.Net.WebSocket/API/Gateway/IdentifyParams.cs +++ b/src/Discord.Net.WebSocket/API/Gateway/IdentifyParams.cs @@ -1,4 +1,5 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 +using Discord.WebSocket; using Newtonsoft.Json; using System.Collections.Generic; @@ -17,5 +18,7 @@ namespace Discord.API.Gateway public Optional ShardingParams { get; set; } [JsonProperty("guild_subscriptions")] public Optional GuildSubscriptions { get; set; } + [JsonProperty("presence")] + public Optional Presence { get; set; } } } diff --git a/src/Discord.Net.WebSocket/ConnectionManager.cs b/src/Discord.Net.WebSocket/ConnectionManager.cs index 8c9c743cb..c0a7f173c 100644 --- a/src/Discord.Net.WebSocket/ConnectionManager.cs +++ b/src/Discord.Net.WebSocket/ConnectionManager.cs @@ -3,6 +3,7 @@ using System; using System.Threading; using System.Threading.Tasks; using Discord.Net; +using Discord.WebSocket; namespace Discord { @@ -53,7 +54,7 @@ namespace Discord }); } - public virtual async Task StartAsync() + public virtual async Task StartAsync(SocketPresence? presence = null) { await AcquireConnectionLock().ConfigureAwait(false); var reconnectCancelToken = new CancellationTokenSource(); diff --git a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs index 9313f0711..4d9221241 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs @@ -215,7 +215,7 @@ namespace Discord.API await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false); } - public async Task SendIdentifyAsync(int largeThreshold = 100, int shardID = 0, int totalShards = 1, bool guildSubscriptions = true, RequestOptions options = null) + public async Task SendIdentifyAsync(int largeThreshold = 100, int shardID = 0, int totalShards = 1, bool guildSubscriptions = true, Optional presence = default, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var props = new Dictionary @@ -227,7 +227,8 @@ namespace Discord.API Token = AuthToken, Properties = props, LargeThreshold = largeThreshold, - GuildSubscriptions = guildSubscriptions + GuildSubscriptions = guildSubscriptions, + Presence = presence }; if (totalShards > 1) msg.ShardingParams = new int[] { shardID, totalShards }; diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index ed142d001..2dc7ee18c 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -221,6 +221,25 @@ namespace Discord.WebSocket /// public override async Task StartAsync() => await _connection.StartAsync().ConfigureAwait(false); + + /// + public async Task StartAsync(UserStatus status, string name = null, string streamUrl = null, ActivityType type = ActivityType.Playing) + { + Status = status; + if (status == UserStatus.AFK) + _statusSince = DateTimeOffset.UtcNow; + else + _statusSince = null; + if (name != null) + { + if (streamUrl != null) + Activity = new StreamingGame(name, streamUrl); + else + Activity = new Game(name, type); + } + await StartAsync().ConfigureAwait(false); + } + /// public override async Task StopAsync() => await _connection.StopAsync().ConfigureAwait(false); @@ -242,14 +261,27 @@ namespace Discord.WebSocket else { await _gatewayLogger.DebugAsync("Identifying").ConfigureAwait(false); - await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, guildSubscriptions: _guildSubscriptions).ConfigureAwait(false); + if (Activity is RichGame) + throw new NotSupportedException("Outgoing Rich Presences are not supported via WebSocket."); + await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, guildSubscriptions: _guildSubscriptions, presence: new StatusUpdateParams + { + Game = Activity == null ? null : new GameModel + { + Name = Activity.Name, + Type = Activity.Type, + StreamUrl = Activity is StreamingGame sg ? sg.Url : null, + }, + Status = Status, + IsAFK = Status == UserStatus.AFK, + IdleSince = _statusSince != null ? _statusSince.Value.ToUnixTimeMilliseconds() : (long?)null + }).ConfigureAwait(false); } //Wait for READY await _connection.WaitAsync().ConfigureAwait(false); - await _gatewayLogger.DebugAsync("Sending Status").ConfigureAwait(false); - await SendStatusAsync().ConfigureAwait(false); + /*await _gatewayLogger.DebugAsync("Sending Status").ConfigureAwait(false); + await SendStatusAsync().ConfigureAwait(false);*/ } finally {