diff --git a/src/Discord.Net/API/DiscordAPIClient.cs b/src/Discord.Net/API/DiscordAPIClient.cs index 1a1d4d0c5..83ad8e244 100644 --- a/src/Discord.Net/API/DiscordAPIClient.cs +++ b/src/Discord.Net/API/DiscordAPIClient.cs @@ -918,17 +918,28 @@ namespace Discord.API //Was this an empty batch? if (models.Length == 0) break; + //We can't assume these messages to be sorted by id (fails in rare cases), lets search for the highest/lowest id ourselves switch (args.RelativeDirection) { case Direction.Before: case Direction.Around: default: result[i] = models; - relativeId = models[models.Length - 1].Id; + relativeId = ulong.MaxValue; + for (int j = 0; j < models.Length; j++) + { + if (models[j].Id < relativeId.Value) + relativeId = models[j].Id; + } break; case Direction.After: result[runs - i - 1] = models; - relativeId = models[0].Id; + relativeId = ulong.MinValue; + for (int j = 0; j < models.Length; j++) + { + if (models[j].Id > relativeId.Value) + relativeId = models[j].Id; + } break; } diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 7231db649..c9ed91a65 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -194,11 +194,23 @@ namespace Discord return null; } /// - public virtual async Task> GetGuildsAsync() + public virtual async Task> GetGuildSummariesAsync() { var models = await ApiClient.GetMyGuildsAsync().ConfigureAwait(false); return models.Select(x => new UserGuild(this, x)).ToImmutableArray(); - + } + /// + public virtual async Task> GetGuildsAsync() + { + var summaryModels = await ApiClient.GetMyGuildsAsync().ConfigureAwait(false); + var guilds = ImmutableArray.CreateBuilder(summaryModels.Count); + foreach (var summaryModel in summaryModels) + { + var guildModel = await ApiClient.GetGuildAsync(summaryModel.Id).ConfigureAwait(false); + if (guildModel != null) + guilds.Add(new Guild(this, guildModel)); + } + return guilds.ToImmutable(); } /// public virtual async Task CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null) diff --git a/src/Discord.Net/DiscordSocketClient.cs b/src/Discord.Net/DiscordSocketClient.cs index 8e29b1097..5d3194dd8 100644 --- a/src/Discord.Net/DiscordSocketClient.cs +++ b/src/Discord.Net/DiscordSocketClient.cs @@ -190,24 +190,29 @@ namespace Discord ConnectionState = ConnectionState.Disconnecting; await _gatewayLogger.InfoAsync("Disconnecting").ConfigureAwait(false); + await _gatewayLogger.DebugAsync("Disconnecting - CancelToken").ConfigureAwait(false); //Signal tasks to complete try { _cancelToken.Cancel(); } catch { } + await _gatewayLogger.DebugAsync("Disconnecting - ApiClient").ConfigureAwait(false); //Disconnect from server await ApiClient.DisconnectAsync().ConfigureAwait(false); //Wait for tasks to complete + await _gatewayLogger.DebugAsync("Disconnecting - Heartbeat").ConfigureAwait(false); var heartbeatTask = _heartbeatTask; if (heartbeatTask != null) await heartbeatTask.ConfigureAwait(false); _heartbeatTask = null; + await _gatewayLogger.DebugAsync("Disconnecting - Guild Downloader").ConfigureAwait(false); var guildDownloadTask = _guildDownloadTask; if (guildDownloadTask != null) await guildDownloadTask.ConfigureAwait(false); _guildDownloadTask = null; //Clear large guild queue + await _gatewayLogger.DebugAsync("Disconnecting - Clean Large Guilds").ConfigureAwait(false); while (_largeGuilds.TryDequeue(out guildId)) { } ConnectionState = ConnectionState.Disconnected; @@ -293,10 +298,14 @@ namespace Discord else return Task.FromResult(null); } - public override Task> GetGuildsAsync() + public override Task> GetGuildSummariesAsync() { return Task.FromResult>(Guilds); } + public override Task> GetGuildsAsync() + { + return Task.FromResult>(Guilds); + } internal CachedGuild AddGuild(ExtendedGuild model, DataStore dataStore) { var guild = new CachedGuild(this, model, dataStore); diff --git a/src/Discord.Net/IDiscordClient.cs b/src/Discord.Net/IDiscordClient.cs index 796eb2611..2163c7dcd 100644 --- a/src/Discord.Net/IDiscordClient.cs +++ b/src/Discord.Net/IDiscordClient.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; namespace Discord { //TODO: Add docstrings + //TODO: Docstrings should explain when REST requests are sent and how many public interface IDiscordClient : IDisposable { LoginState LoginState { get; } @@ -28,7 +29,8 @@ namespace Discord Task> GetConnectionsAsync(); Task GetGuildAsync(ulong id); - Task> GetGuildsAsync(); + Task> GetGuildsAsync(); + Task> GetGuildSummariesAsync(); Task CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null); Task GetInviteAsync(string inviteIdOrXkcd);