diff --git a/src/Discord.Net/API/Client/GatewaySocket/Commands/UpdateStatus.cs b/src/Discord.Net/API/Client/GatewaySocket/Commands/UpdateStatus.cs index 4ebe5633b..3af68d09c 100644 --- a/src/Discord.Net/API/Client/GatewaySocket/Commands/UpdateStatus.cs +++ b/src/Discord.Net/API/Client/GatewaySocket/Commands/UpdateStatus.cs @@ -9,9 +9,13 @@ namespace Discord.API.Client.GatewaySocket object IWebSocketMessage.Payload => this; bool IWebSocketMessage.IsPrivate => false; - [JsonProperty("idle_since")] + [JsonProperty("afk")] + public bool? Afk { get; set; } + [JsonProperty("since")] public long? IdleSince { get; set; } [JsonProperty("game")] public Game Game { get; set; } + [JsonProperty("status")] + public string Status { get; set; } } } diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 9dacfe71a..4bb076ba1 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -324,8 +324,8 @@ namespace Discord public void SetStatus(UserStatus status) { if (status == null) throw new ArgumentNullException(nameof(status)); - if (status != UserStatus.Online && status != UserStatus.Idle) - throw new ArgumentException($"Invalid status, must be {UserStatus.Online} or {UserStatus.Idle}", nameof(status)); + if (status != UserStatus.Online && status != UserStatus.Idle && status != UserStatus.DoNotDisturb && status != UserStatus.Invisible) + throw new ArgumentException($"Invalid status, must be {UserStatus.Online}, {UserStatus.Idle}, {UserStatus.DoNotDisturb} or {UserStatus.Invisible}", nameof(status)); Status = status; SendStatus(); @@ -360,7 +360,7 @@ namespace Discord } var socket = GatewaySocket; if (socket != null) - socket.SendUpdateStatus(Status == UserStatus.Idle ? EpochTime.GetMilliseconds() - (10 * 60 * 1000) : (long?)null, CurrentGame); + socket.SendUpdateStatus(Status == UserStatus.Idle ? EpochTime.GetMilliseconds() - (10 * 60 * 1000) : (long?)null, CurrentGame, Status == UserStatus.Idle, Status); } #region Channels diff --git a/src/Discord.Net/Enums/UserStatus.cs b/src/Discord.Net/Enums/UserStatus.cs index 80def4234..c4cd40176 100644 --- a/src/Discord.Net/Enums/UserStatus.cs +++ b/src/Discord.Net/Enums/UserStatus.cs @@ -8,6 +8,10 @@ public static UserStatus Idle { get; } = new UserStatus("idle"); /// User is offline. public static UserStatus Offline { get; } = new UserStatus("offline"); + /// User is busy. + public static UserStatus DoNotDisturb { get; } = new UserStatus("dnd"); + /// User is invisible. + public static UserStatus Invisible { get; } = new UserStatus("invisible"); private UserStatus(string value) : base(value) { } @@ -24,6 +28,10 @@ return Idle; case "offline": return Offline; + case "dnd": + return DoNotDisturb; + case "invisible": + return Invisible; default: return new UserStatus(value); } diff --git a/src/Discord.Net/Net/WebSockets/GatewaySocket.cs b/src/Discord.Net/Net/WebSockets/GatewaySocket.cs index d9f7bf520..8f19983ee 100644 --- a/src/Discord.Net/Net/WebSockets/GatewaySocket.cs +++ b/src/Discord.Net/Net/WebSockets/GatewaySocket.cs @@ -170,11 +170,13 @@ namespace Discord.Net.WebSockets => QueueMessage(new ResumeCommand { SessionId = SessionId, Sequence = _lastSequence }); public override void SendHeartbeat() => QueueMessage(new HeartbeatCommand()); - public void SendUpdateStatus(long? idleSince, Game? game) + public void SendUpdateStatus(long? idleSince, Game? game, bool? afk, UserStatus status) => QueueMessage(new UpdateStatusCommand { IdleSince = idleSince, - Game = game != null ? new APIGame { Name = game.Value.Name, Type = game.Value.Type, Url = game.Value.Url } : null + Game = game != null ? new APIGame { Name = game.Value.Name, Type = game.Value.Type, Url = game.Value.Url } : null, + Afk = afk, + Status = status.Value }); public void SendUpdateVoice(ulong? serverId, ulong? channelId, bool isSelfMuted, bool isSelfDeafened) => QueueMessage(new UpdateVoiceCommand { GuildId = serverId, ChannelId = channelId, IsSelfMuted = isSelfMuted, IsSelfDeafened = isSelfDeafened });