diff --git a/src/Discord.Net.WebSocket/API/Gateway/StatusUpdateParams.cs b/src/Discord.Net.WebSocket/API/Gateway/StatusUpdateParams.cs index e685e5e57..5fec8b4bd 100644 --- a/src/Discord.Net.WebSocket/API/Gateway/StatusUpdateParams.cs +++ b/src/Discord.Net.WebSocket/API/Gateway/StatusUpdateParams.cs @@ -12,7 +12,7 @@ namespace Discord.API.Gateway public long? IdleSince { get; set; } [JsonProperty("afk")] public bool IsAFK { get; set; } - [JsonProperty("activities")] - public Game[] Activities { get; set; } + [JsonProperty("game")] + public Game Game { get; set; } } } diff --git a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs index 5a926ba26..d14a314d6 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs @@ -216,7 +216,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, GatewayIntents? gatewayIntents = null, (UserStatus, bool, long?, GameModel[])? presence = null, RequestOptions options = null) + public async Task SendIdentifyAsync(int largeThreshold = 100, int shardID = 0, int totalShards = 1, bool guildSubscriptions = true, GatewayIntents? gatewayIntents = null, (UserStatus, bool, long?, GameModel)? presence = null, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var props = new Dictionary @@ -246,7 +246,7 @@ namespace Discord.API Status = presence.Value.Item1, IsAFK = presence.Value.Item2, IdleSince = presence.Value.Item3, - Activities = presence.Value.Item4 + Game = presence.Value.Item4, }; } @@ -268,7 +268,7 @@ namespace Discord.API options = RequestOptions.CreateOrClone(options); await SendGatewayAsync(GatewayOpCode.Heartbeat, lastSeq, options: options).ConfigureAwait(false); } - public async Task SendStatusUpdateAsync(UserStatus status, bool isAFK, long? since, GameModel[] game, RequestOptions options = null) + public async Task SendStatusUpdateAsync(UserStatus status, bool isAFK, long? since, GameModel game, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var args = new StatusUpdateParams @@ -276,7 +276,7 @@ namespace Discord.API Status = status, IdleSince = since, IsAFK = isAFK, - Activities = game + Game = game }; options.BucketId = GatewayBucket.Get(GatewayBucketType.PresenceUpdate).Id; await SendGatewayAsync(GatewayOpCode.StatusUpdate, args, options: options).ConfigureAwait(false); diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 8fa09e8f6..0a2123ef2 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -57,7 +57,8 @@ namespace Discord.WebSocket /// public override int Latency { get; protected set; } /// - public override UserStatus Status { get; protected set; } = UserStatus.Online; + public override UserStatus Status { get => _status ?? UserStatus.Online; protected set => _status = value; } + private UserStatus? _status; /// public override IActivity Activity { get => _activity.GetValueOrDefault(); protected set => _activity = Optional.Create(value); } private Optional _activity; @@ -449,22 +450,25 @@ namespace Discord.WebSocket return; CurrentUser.Presence = new SocketPresence(Status, Activity, null, null); - var presence = BuildCurrentStatus(); + var presence = BuildCurrentStatus() ?? (UserStatus.Online, false, null, null); await ApiClient.SendStatusUpdateAsync( - presence.Item1, - presence.Item2, - presence.Item3, - presence.Item4).ConfigureAwait(false); + status: presence.Item1, + isAFK: presence.Item2, + since: presence.Item3, + game: presence.Item4).ConfigureAwait(false); } - private (UserStatus, bool, long?, GameModel[]) BuildCurrentStatus() + private (UserStatus, bool, long?, GameModel)? BuildCurrentStatus() { - var status = Status; + var status = _status; var statusSince = _statusSince; var activity = _activity; - GameModel[] gameModels = null; + if (status == null && !activity.IsSpecified) + return null; + + GameModel game = null; // Discord only accepts rich presence over RPC, don't even bother building a payload if (activity.GetValueOrDefault() != null) @@ -476,15 +480,15 @@ namespace Discord.WebSocket gameModel.Type = Activity.Type; if (Activity is StreamingGame streamGame) gameModel.StreamUrl = streamGame.Url; - gameModels = new[] { gameModel }; + game = gameModel; } else if (activity.IsSpecified) - gameModels = new GameModel[0]; + game = null; - return (status, + return (status ?? UserStatus.Online, status == UserStatus.AFK, statusSince != null ? _statusSince.Value.ToUnixTimeMilliseconds() : (long?)null, - gameModels); + game); } private async Task ProcessMessageAsync(GatewayOpCode opCode, int? seq, string type, object payload)