@@ -918,17 +918,28 @@ namespace Discord.API | |||||
//Was this an empty batch? | //Was this an empty batch? | ||||
if (models.Length == 0) break; | 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) | switch (args.RelativeDirection) | ||||
{ | { | ||||
case Direction.Before: | case Direction.Before: | ||||
case Direction.Around: | case Direction.Around: | ||||
default: | default: | ||||
result[i] = models; | 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; | break; | ||||
case Direction.After: | case Direction.After: | ||||
result[runs - i - 1] = models; | 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; | break; | ||||
} | } | ||||
@@ -194,11 +194,23 @@ namespace Discord | |||||
return null; | return null; | ||||
} | } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public virtual async Task<IReadOnlyCollection<IUserGuild>> GetGuildsAsync() | |||||
public virtual async Task<IReadOnlyCollection<IUserGuild>> GetGuildSummariesAsync() | |||||
{ | { | ||||
var models = await ApiClient.GetMyGuildsAsync().ConfigureAwait(false); | var models = await ApiClient.GetMyGuildsAsync().ConfigureAwait(false); | ||||
return models.Select(x => new UserGuild(this, x)).ToImmutableArray(); | return models.Select(x => new UserGuild(this, x)).ToImmutableArray(); | ||||
} | |||||
/// <inheritdoc /> | |||||
public virtual async Task<IReadOnlyCollection<IGuild>> GetGuildsAsync() | |||||
{ | |||||
var summaryModels = await ApiClient.GetMyGuildsAsync().ConfigureAwait(false); | |||||
var guilds = ImmutableArray.CreateBuilder<IGuild>(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(); | |||||
} | } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public virtual async Task<IGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null) | public virtual async Task<IGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null) | ||||
@@ -190,24 +190,29 @@ namespace Discord | |||||
ConnectionState = ConnectionState.Disconnecting; | ConnectionState = ConnectionState.Disconnecting; | ||||
await _gatewayLogger.InfoAsync("Disconnecting").ConfigureAwait(false); | await _gatewayLogger.InfoAsync("Disconnecting").ConfigureAwait(false); | ||||
await _gatewayLogger.DebugAsync("Disconnecting - CancelToken").ConfigureAwait(false); | |||||
//Signal tasks to complete | //Signal tasks to complete | ||||
try { _cancelToken.Cancel(); } catch { } | try { _cancelToken.Cancel(); } catch { } | ||||
await _gatewayLogger.DebugAsync("Disconnecting - ApiClient").ConfigureAwait(false); | |||||
//Disconnect from server | //Disconnect from server | ||||
await ApiClient.DisconnectAsync().ConfigureAwait(false); | await ApiClient.DisconnectAsync().ConfigureAwait(false); | ||||
//Wait for tasks to complete | //Wait for tasks to complete | ||||
await _gatewayLogger.DebugAsync("Disconnecting - Heartbeat").ConfigureAwait(false); | |||||
var heartbeatTask = _heartbeatTask; | var heartbeatTask = _heartbeatTask; | ||||
if (heartbeatTask != null) | if (heartbeatTask != null) | ||||
await heartbeatTask.ConfigureAwait(false); | await heartbeatTask.ConfigureAwait(false); | ||||
_heartbeatTask = null; | _heartbeatTask = null; | ||||
await _gatewayLogger.DebugAsync("Disconnecting - Guild Downloader").ConfigureAwait(false); | |||||
var guildDownloadTask = _guildDownloadTask; | var guildDownloadTask = _guildDownloadTask; | ||||
if (guildDownloadTask != null) | if (guildDownloadTask != null) | ||||
await guildDownloadTask.ConfigureAwait(false); | await guildDownloadTask.ConfigureAwait(false); | ||||
_guildDownloadTask = null; | _guildDownloadTask = null; | ||||
//Clear large guild queue | //Clear large guild queue | ||||
await _gatewayLogger.DebugAsync("Disconnecting - Clean Large Guilds").ConfigureAwait(false); | |||||
while (_largeGuilds.TryDequeue(out guildId)) { } | while (_largeGuilds.TryDequeue(out guildId)) { } | ||||
ConnectionState = ConnectionState.Disconnected; | ConnectionState = ConnectionState.Disconnected; | ||||
@@ -293,10 +298,14 @@ namespace Discord | |||||
else | else | ||||
return Task.FromResult<GuildEmbed?>(null); | return Task.FromResult<GuildEmbed?>(null); | ||||
} | } | ||||
public override Task<IReadOnlyCollection<IUserGuild>> GetGuildsAsync() | |||||
public override Task<IReadOnlyCollection<IUserGuild>> GetGuildSummariesAsync() | |||||
{ | { | ||||
return Task.FromResult<IReadOnlyCollection<IUserGuild>>(Guilds); | return Task.FromResult<IReadOnlyCollection<IUserGuild>>(Guilds); | ||||
} | } | ||||
public override Task<IReadOnlyCollection<IGuild>> GetGuildsAsync() | |||||
{ | |||||
return Task.FromResult<IReadOnlyCollection<IGuild>>(Guilds); | |||||
} | |||||
internal CachedGuild AddGuild(ExtendedGuild model, DataStore dataStore) | internal CachedGuild AddGuild(ExtendedGuild model, DataStore dataStore) | ||||
{ | { | ||||
var guild = new CachedGuild(this, model, dataStore); | var guild = new CachedGuild(this, model, dataStore); | ||||
@@ -8,6 +8,7 @@ using System.Threading.Tasks; | |||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
//TODO: Add docstrings | //TODO: Add docstrings | ||||
//TODO: Docstrings should explain when REST requests are sent and how many | |||||
public interface IDiscordClient : IDisposable | public interface IDiscordClient : IDisposable | ||||
{ | { | ||||
LoginState LoginState { get; } | LoginState LoginState { get; } | ||||
@@ -28,7 +29,8 @@ namespace Discord | |||||
Task<IReadOnlyCollection<IConnection>> GetConnectionsAsync(); | Task<IReadOnlyCollection<IConnection>> GetConnectionsAsync(); | ||||
Task<IGuild> GetGuildAsync(ulong id); | Task<IGuild> GetGuildAsync(ulong id); | ||||
Task<IReadOnlyCollection<IUserGuild>> GetGuildsAsync(); | |||||
Task<IReadOnlyCollection<IGuild>> GetGuildsAsync(); | |||||
Task<IReadOnlyCollection<IUserGuild>> GetGuildSummariesAsync(); | |||||
Task<IGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null); | Task<IGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null); | ||||
Task<IInvite> GetInviteAsync(string inviteIdOrXkcd); | Task<IInvite> GetInviteAsync(string inviteIdOrXkcd); | ||||