| @@ -1,4 +1,5 @@ | |||||
| #pragma warning disable CS1591 | |||||
| #pragma warning disable CS1591 | |||||
| using Discord.WebSocket; | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| @@ -17,5 +18,7 @@ namespace Discord.API.Gateway | |||||
| public Optional<int[]> ShardingParams { get; set; } | public Optional<int[]> ShardingParams { get; set; } | ||||
| [JsonProperty("guild_subscriptions")] | [JsonProperty("guild_subscriptions")] | ||||
| public Optional<bool> GuildSubscriptions { get; set; } | public Optional<bool> GuildSubscriptions { get; set; } | ||||
| [JsonProperty("presence")] | |||||
| public Optional<StatusUpdateParams> Presence { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -3,6 +3,7 @@ using System; | |||||
| using System.Threading; | using System.Threading; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Discord.Net; | using Discord.Net; | ||||
| using Discord.WebSocket; | |||||
| namespace Discord | 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); | await AcquireConnectionLock().ConfigureAwait(false); | ||||
| var reconnectCancelToken = new CancellationTokenSource(); | var reconnectCancelToken = new CancellationTokenSource(); | ||||
| @@ -215,7 +215,7 @@ namespace Discord.API | |||||
| await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false); | 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<StatusUpdateParams> presence = default, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var props = new Dictionary<string, string> | var props = new Dictionary<string, string> | ||||
| @@ -227,7 +227,8 @@ namespace Discord.API | |||||
| Token = AuthToken, | Token = AuthToken, | ||||
| Properties = props, | Properties = props, | ||||
| LargeThreshold = largeThreshold, | LargeThreshold = largeThreshold, | ||||
| GuildSubscriptions = guildSubscriptions | |||||
| GuildSubscriptions = guildSubscriptions, | |||||
| Presence = presence | |||||
| }; | }; | ||||
| if (totalShards > 1) | if (totalShards > 1) | ||||
| msg.ShardingParams = new int[] { shardID, totalShards }; | msg.ShardingParams = new int[] { shardID, totalShards }; | ||||
| @@ -221,6 +221,25 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override async Task StartAsync() | public override async Task StartAsync() | ||||
| => await _connection.StartAsync().ConfigureAwait(false); | => await _connection.StartAsync().ConfigureAwait(false); | ||||
| /// <inheritdoc /> | |||||
| 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); | |||||
| } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override async Task StopAsync() | public override async Task StopAsync() | ||||
| => await _connection.StopAsync().ConfigureAwait(false); | => await _connection.StopAsync().ConfigureAwait(false); | ||||
| @@ -242,14 +261,27 @@ namespace Discord.WebSocket | |||||
| else | else | ||||
| { | { | ||||
| await _gatewayLogger.DebugAsync("Identifying").ConfigureAwait(false); | 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 | //Wait for READY | ||||
| await _connection.WaitAsync().ConfigureAwait(false); | 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 | finally | ||||
| { | { | ||||