diff --git a/docs/guides/samples/command_handler.cs b/docs/guides/samples/command_handler.cs index 42dc47f17..71869415b 100644 --- a/docs/guides/samples/command_handler.cs +++ b/docs/guides/samples/command_handler.cs @@ -50,7 +50,7 @@ public class Program // rather an object stating if the command executed succesfully) var result = await commands.ExecuteAsync(context, argPos, map); if (!result.IsSuccess) - await msg.Channel.SendMessageAsync(result.ErrorReason); + await context.Channel.SendMessageAsync(result.ErrorReason); } -} \ No newline at end of file +} diff --git a/docs/guides/samples/dependency_map_setup.cs b/docs/guides/samples/dependency_map_setup.cs index af791990e..1d25db43c 100644 --- a/docs/guides/samples/dependency_map_setup.cs +++ b/docs/guides/samples/dependency_map_setup.cs @@ -11,7 +11,7 @@ public class Commands var map = new DependencyMap(); map.Add(client); map.Add(commands); - await commands.LoadAssembly(Assembly.GetCurrentAssembly(), map); + await commands.AddModulesAsync(Assembly.GetEntryAssembly()); } // In ConfigureServices, we will inject the Dependency Map with // all of the services our client will use. @@ -21,4 +21,4 @@ public class Commands map.Add(new DatabaseService(map)); } // ... -} \ No newline at end of file +} diff --git a/docs/guides/samples/require_owner.cs b/docs/guides/samples/require_owner.cs index c8d3c2071..567b3d2af 100644 --- a/docs/guides/samples/require_owner.cs +++ b/docs/guides/samples/require_owner.cs @@ -4,7 +4,7 @@ public class RequireOwnerAttribute : PreconditionAttribute { // Override the CheckPermissions method - public override Task CheckPermissions(CommandContext context, CommandInfo command, IDependencyMap map) + public async override Task CheckPermissions(CommandContext context, CommandInfo command, IDependencyMap map) { // Get the ID of the bot's owner var ownerId = (await map.Get().GetApplicationInfoAsync()).Owner.Id; @@ -15,4 +15,4 @@ public class RequireOwnerAttribute : PreconditionAttribute else return PreconditionResult.FromError("You must be the owner of the bot to run this command."); } -} \ No newline at end of file +} diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index b6659fea3..d5f4bee7e 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -214,9 +214,9 @@ namespace Discord.Commands public SearchResult Search(CommandContext context, int argPos) => Search(context, context.Message.Content.Substring(argPos)); public SearchResult Search(CommandContext context, string input) { - input = _caseSensitive ? input : input.ToLowerInvariant(); - var matches = _map.GetCommands(input).OrderByDescending(x => x.Priority).ToImmutableArray(); - + string searchInput = _caseSensitive ? input : input.ToLowerInvariant(); + var matches = _map.GetCommands(searchInput).OrderByDescending(x => x.Priority).ToImmutableArray(); + if (matches.Length > 0) return SearchResult.FromSuccess(input, matches); else diff --git a/src/Discord.Net.Rpc/DiscordRpcClient.cs b/src/Discord.Net.Rpc/DiscordRpcClient.cs index 3ca288b12..9efa2d312 100644 --- a/src/Discord.Net.Rpc/DiscordRpcClient.cs +++ b/src/Discord.Net.Rpc/DiscordRpcClient.cs @@ -70,21 +70,17 @@ namespace Discord.Rpc => new API.DiscordRpcApiClient(clientId, DiscordRestConfig.UserAgent, origin, config.RestClientProvider, config.WebSocketProvider, requestQueue: new RequestQueue()); /// - public Task ConnectAsync() => ConnectAsync(false); - internal async Task ConnectAsync(bool ignoreLoginCheck) + public async Task ConnectAsync() { await _connectionLock.WaitAsync().ConfigureAwait(false); try { - await ConnectInternalAsync(ignoreLoginCheck, false).ConfigureAwait(false); + await ConnectInternalAsync(false).ConfigureAwait(false); } finally { _connectionLock.Release(); } } - private async Task ConnectInternalAsync(bool ignoreLoginCheck, bool isReconnecting) - { - if (!ignoreLoginCheck && LoginState != LoginState.LoggedIn) - throw new InvalidOperationException("You must log in before connecting."); - + private async Task ConnectInternalAsync(bool isReconnecting) + { if (!isReconnecting && _reconnectCancelToken != null && !_reconnectCancelToken.IsCancellationRequested) _reconnectCancelToken.Cancel(); @@ -198,7 +194,7 @@ namespace Discord.Rpc try { if (cancelToken.IsCancellationRequested) return; - await ConnectInternalAsync(false, true).ConfigureAwait(false); + await ConnectInternalAsync(true).ConfigureAwait(false); _reconnectTask = null; return; } @@ -223,7 +219,7 @@ namespace Discord.Rpc public async Task AuthorizeAsync(string[] scopes, string rpcToken = null, RequestOptions options = null) { - await ConnectAsync(true).ConfigureAwait(false); + await ConnectAsync().ConfigureAwait(false); var result = await ApiClient.SendAuthorizeAsync(scopes, rpcToken, options).ConfigureAwait(false); await DisconnectAsync().ConfigureAwait(false); return result.Code; diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 0d58d6222..c28e30b51 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -57,6 +57,7 @@ namespace Discord.WebSocket internal ClientState State { get; private set; } internal int ConnectionTimeout { get; private set; } internal WebSocketProvider WebSocketProvider { get; private set; } + internal bool DownloadUsersOnGuildAvailable { get; private set; } public new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient; public new SocketSelfUser CurrentUser { get { return base.CurrentUser as SocketSelfUser; } private set { base.CurrentUser = value; } } @@ -76,6 +77,7 @@ namespace Discord.WebSocket LargeThreshold = config.LargeThreshold; AudioMode = config.AudioMode; WebSocketProvider = config.WebSocketProvider; + DownloadUsersOnGuildAvailable = config.DownloadUsersOnGuildAvailable; ConnectionTimeout = config.ConnectionTimeout; State = new ClientState(0, 0); @@ -108,6 +110,15 @@ namespace Discord.WebSocket GuildUnavailable += async g => await _gatewayLogger.VerboseAsync($"Disconnected from {g.Name}").ConfigureAwait(false); LatencyUpdated += async (old, val) => await _gatewayLogger.VerboseAsync($"Latency = {val} ms").ConfigureAwait(false); + if (DownloadUsersOnGuildAvailable) + { + GuildAvailable += g => + { + var _ = g.DownloadUsersAsync(); + return Task.CompletedTask; + }; + } + _voiceRegions = ImmutableDictionary.Create(); _largeGuilds = new ConcurrentQueue(); } @@ -1663,7 +1674,7 @@ namespace Discord.WebSocket { if (_heartbeatTime != 0) //Server never responded to our last heartbeat { - if (ConnectionState == ConnectionState.Connected && (_guildDownloadTask?.IsCompleted ?? false)) + if (ConnectionState == ConnectionState.Connected && (_guildDownloadTask?.IsCompleted ?? true)) { await _gatewayLogger.WarningAsync("Server missed last heartbeat").ConfigureAwait(false); await StartReconnectAsync(new Exception("Server missed last heartbeat")).ConfigureAwait(false); diff --git a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs index dc0347a1c..9bf337f8e 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs @@ -28,5 +28,8 @@ namespace Discord.WebSocket /// Gets or sets the provider used to generate new websocket connections. public WebSocketProvider WebSocketProvider { get; set; } = () => new DefaultWebSocketClient(); + + /// Gets or sets whether or not all users should be downloaded as guilds come available. + public bool DownloadUsersOnGuildAvailable { get; set; } = false; } }