diff --git a/src/Discord.Net/API/Common/Channel.cs b/src/Discord.Net/API/Common/Channel.cs index b0789b111..19cd79cc7 100644 --- a/src/Discord.Net/API/Common/Channel.cs +++ b/src/Discord.Net/API/Common/Channel.cs @@ -11,14 +11,14 @@ namespace Discord.API public bool IsPrivate { get; set; } [JsonProperty("last_message_id")] public ulong? LastMessageId { get; set; } + [JsonProperty("type")] + public ChannelType Type { get; set; } //GuildChannel [JsonProperty("guild_id")] public Optional GuildId { get; set; } [JsonProperty("name")] public Optional Name { get; set; } - [JsonProperty("type")] - public Optional Type { get; set; } [JsonProperty("position")] public Optional Position { get; set; } [JsonProperty("permission_overwrites")] @@ -34,8 +34,9 @@ namespace Discord.API [JsonProperty("user_limit")] public Optional UserLimit { get; set; } - //DMChannel - [JsonProperty("recipient")] - public Optional Recipient { get; set; } + //DMChannel or GroupChannel + [JsonProperty("recipients")] + public Optional Recipients { get; set; } + } } diff --git a/src/Discord.Net/API/Common/RelationshipType.cs b/src/Discord.Net/API/Common/RelationshipType.cs index 53be3a98f..8ed431d09 100644 --- a/src/Discord.Net/API/Common/RelationshipType.cs +++ b/src/Discord.Net/API/Common/RelationshipType.cs @@ -4,6 +4,7 @@ { Friend = 1, Blocked = 2, - Pending = 4 + Incoming = 3, + Outgoing = 3 } } diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index d80b374f4..94d6ab152 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -166,7 +166,11 @@ namespace Discord } } else - return new DMChannel(this, new User(model.Recipient.Value), model); + { + if (model.Recipients.Value.Count() == 1) + return new DMChannel(this, new User(model.Recipients.Value[0]), model); + throw new NotImplementedException("Groups are not implemented."); + } } return null; } @@ -174,7 +178,7 @@ namespace Discord public virtual async Task> GetDMChannelsAsync() { var models = await ApiClient.GetMyDMsAsync().ConfigureAwait(false); - return models.Select(x => new DMChannel(this, new User(x.Recipient.Value), x)).ToImmutableArray(); + return models.Where(m => m.Recipients.Value.Count() == 1).Select(x => new DMChannel(this, new User(x.Recipients.Value[0]), x)).ToImmutableArray(); } /// diff --git a/src/Discord.Net/DiscordConfig.cs b/src/Discord.Net/DiscordConfig.cs index 75d5b7a21..599af4410 100644 --- a/src/Discord.Net/DiscordConfig.cs +++ b/src/Discord.Net/DiscordConfig.cs @@ -8,7 +8,7 @@ namespace Discord public static string Version { get; } = typeof(DiscordConfig).GetTypeInfo().Assembly?.GetName().Version.ToString(3) ?? "Unknown"; public static string UserAgent { get; } = $"DiscordBot (https://github.com/RogueException/Discord.Net, v{Version})"; - public const int GatewayAPIVersion = 5; + public const int GatewayAPIVersion = 6; public const string GatewayEncoding = "json"; public const string ClientAPIUrl = "https://discordapp.com/api/"; diff --git a/src/Discord.Net/DiscordSocketClient.cs b/src/Discord.Net/DiscordSocketClient.cs index f3948a1eb..c3aa4677c 100644 --- a/src/Discord.Net/DiscordSocketClient.cs +++ b/src/Discord.Net/DiscordSocketClient.cs @@ -335,7 +335,7 @@ namespace Discord } internal CachedDMChannel AddDMChannel(API.Channel model, DataStore dataStore) { - var recipient = GetOrAddUser(model.Recipient.Value, dataStore); + var recipient = GetOrAddUser(model.Recipients.Value[0], dataStore); var channel = new CachedDMChannel(this, new CachedDMUser(recipient), model); recipient.AddRef(); dataStore.AddDMChannel(channel); @@ -442,6 +442,9 @@ namespace Discord _lastSeq = seq.Value; try { + string writeOutput = $"PACKET ---\n OPCODE: {opCode}\nSEQ: {(seq.HasValue ? seq.Value : -1)}\nTYPE: {type}\n========== BEGIN PAYLOAD ==========\n\n{payload}\n========================="; + System.IO.File.WriteAllText($"./discord-debug/{opCode}-{DateTime.Now.ToFileTime()}", writeOutput); + switch (opCode) { case GatewayOpCode.Hello: @@ -505,7 +508,8 @@ namespace Discord await _gatewayLogger.DebugAsync("Received Dispatch (READY)").ConfigureAwait(false); var data = (payload as JToken).ToObject(_serializer); - var dataStore = new DataStore( data.Guilds.Length, data.PrivateChannels.Length); + var privateChannels = data.PrivateChannels.Where(c => c.Recipients.IsSpecified && c.Recipients.Value.Count() == 1).ToArray(); + var dataStore = new DataStore( data.Guilds.Length, privateChannels.Length); var currentUser = new CachedSelfUser(this, data.User); int unavailableGuilds = 0; @@ -517,8 +521,8 @@ namespace Discord if (model.Unavailable == true) unavailableGuilds++; } - for (int i = 0; i < data.PrivateChannels.Length; i++) - AddDMChannel(data.PrivateChannels[i], dataStore); + for (int i = 0; i < privateChannels.Length; i++) + AddDMChannel(privateChannels[i], dataStore); _sessionId = data.SessionId; _currentUser = currentUser; @@ -740,7 +744,7 @@ namespace Discord } } else - channel = RemoveDMChannel(data.Recipient.Value.Id); + channel = RemoveDMChannel(data.Id); if (channel != null) await _channelDestroyedEvent.InvokeAsync(channel).ConfigureAwait(false); else @@ -1260,7 +1264,7 @@ namespace Discord catch (Exception ex) { await _gatewayLogger.ErrorAsync($"Error handling {opCode}{(type != null ? $" ({type})" : "")}", ex).ConfigureAwait(false); - return; + throw; } #if BENCHMARK } diff --git a/src/Discord.Net/Entities/Channels/ChannelType.cs b/src/Discord.Net/Entities/Channels/ChannelType.cs index e6a3a1e00..ccffa1297 100644 --- a/src/Discord.Net/Entities/Channels/ChannelType.cs +++ b/src/Discord.Net/Entities/Channels/ChannelType.cs @@ -2,8 +2,9 @@ { public enum ChannelType : byte { - DM, - Text, - Voice + DM = 1, + Text = 0, + Voice = 2, + Group = 3 } } diff --git a/src/Discord.Net/Entities/Channels/DMChannel.cs b/src/Discord.Net/Entities/Channels/DMChannel.cs index a5adc4284..f1635ad8f 100644 --- a/src/Discord.Net/Entities/Channels/DMChannel.cs +++ b/src/Discord.Net/Entities/Channels/DMChannel.cs @@ -30,7 +30,7 @@ namespace Discord { if (/*source == UpdateSource.Rest && */IsAttached) return; - (Recipient as User).Update(model.Recipient.Value, source); + (Recipient as User).Update(model.Recipients.Value[0], source); } public async Task UpdateAsync() diff --git a/src/Discord.Net/Entities/Guilds/Guild.cs b/src/Discord.Net/Entities/Guilds/Guild.cs index 1e400cce0..9589420a3 100644 --- a/src/Discord.Net/Entities/Guilds/Guild.cs +++ b/src/Discord.Net/Entities/Guilds/Guild.cs @@ -296,14 +296,14 @@ namespace Discord internal GuildChannel ToChannel(API.Channel model) { - switch (model.Type.Value) + switch (model.Type) { case ChannelType.Text: return new TextChannel(this, model); case ChannelType.Voice: return new VoiceChannel(this, model); default: - throw new InvalidOperationException($"Unknown channel type: {model.Type.Value}"); + throw new InvalidOperationException($"Unknown channel type: {model.Type}"); } } diff --git a/src/Discord.Net/Entities/WebSocket/CachedGuild.cs b/src/Discord.Net/Entities/WebSocket/CachedGuild.cs index 569347d73..55b7b6e6b 100644 --- a/src/Discord.Net/Entities/WebSocket/CachedGuild.cs +++ b/src/Discord.Net/Entities/WebSocket/CachedGuild.cs @@ -311,14 +311,14 @@ namespace Discord new internal ICachedGuildChannel ToChannel(ChannelModel model) { - switch (model.Type.Value) + switch (model.Type) { case ChannelType.Text: return new CachedTextChannel(this, model); case ChannelType.Voice: return new CachedVoiceChannel(this, model); default: - throw new InvalidOperationException($"Unknown channel type: {model.Type.Value}"); + throw new InvalidOperationException($"Unknown channel type: {model.Type}"); } } diff --git a/src/Discord.Net/Net/Converters/ChannelTypeConverter.cs b/src/Discord.Net/Net/Converters/ChannelTypeConverter.cs index 48bcbd755..0c4f5baf5 100644 --- a/src/Discord.Net/Net/Converters/ChannelTypeConverter.cs +++ b/src/Discord.Net/Net/Converters/ChannelTypeConverter.cs @@ -13,12 +13,17 @@ namespace Discord.Net.Converters public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - switch ((string)reader.Value) + // TODO: This should probably just be a cast to an enum + switch ((long)reader.Value) { - case "text": + case 0: return ChannelType.Text; - case "voice": + case 1: + return ChannelType.DM; + case 2: return ChannelType.Voice; + case 3: + return ChannelType.Group; default: throw new JsonSerializationException("Unknown channel type"); } @@ -26,7 +31,7 @@ namespace Discord.Net.Converters public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - switch ((ChannelType)value) + /*switch ((ChannelType)value) { case ChannelType.Text: writer.WriteValue("text"); @@ -36,7 +41,8 @@ namespace Discord.Net.Converters break; default: throw new JsonSerializationException("Invalid channel type"); - } + }*/ + writer.WriteValue((int)value); } } }