statusProvider)
{
this.statusProvider = statusProvider;
return this;
}
/**
* Sets the {@link java.util.concurrent.ThreadFactory ThreadFactory} that will be used by the internal executor
* of the ShardManager.
* Note: This will not affect Threads created by any JDA instance.
*
* @param threadFactory
* The ThreadFactory or {@code null} to reset to the default value.
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setThreadFactory(@Nullable final ThreadFactory threadFactory)
{
this.threadFactory = threadFactory;
return this;
}
/**
* Sets the {@link okhttp3.OkHttpClient.Builder Builder} that will be used by JDA's requester.
* This can be used to set things such as connection timeout and proxy.
*
* @param builder
* The new {@link okhttp3.OkHttpClient.Builder OkHttpClient.Builder} to use.
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setHttpClientBuilder(@Nullable OkHttpClient.Builder builder)
{
this.httpClientBuilder = builder;
return this;
}
/**
* Sets the {@link okhttp3.OkHttpClient OkHttpClient} that will be used by JDAs requester.
*
This can be used to set things such as connection timeout and proxy.
*
* @param client
* The new {@link okhttp3.OkHttpClient OkHttpClient} to use
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setHttpClient(@Nullable OkHttpClient client)
{
this.httpClient = client;
return this;
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} that should be used in
* the JDA rate-limit handler. Changing this can drastically change the JDA behavior for RestAction execution
* and should be handled carefully. Only change this pool if you know what you're doing.
*
This will override the rate-limit pool provider set from {@link #setRateLimitSchedulerProvider(ThreadPoolProvider)}.
*
This automatically disables the automatic shutdown of the rate-limit pool, you can enable
* it using {@link #setRateLimitScheduler(ScheduledExecutorService, boolean) setRateLimiPool(executor, true)}
*
*
This is used mostly by the Rate-Limiter to handle backoff delays by using scheduled executions.
* Besides that it is also used by planned execution for {@link net.dv8tion.jda.api.requests.RestAction#queueAfter(long, TimeUnit)}
* and similar methods. Requests are handed off to the {@link #setRateLimitElastic(ExecutorService) elastic pool} for blocking execution.
*
*
Default: Shared {@link ScheduledThreadPoolExecutor} with ({@code 2 * } log({@link #setShardsTotal(int) shard_total})) threads.
*
* @param pool
* The thread-pool to use for rate-limit handling
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setRateLimitScheduler(@Nullable ScheduledExecutorService pool)
{
return setRateLimitScheduler(pool, pool == null);
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} that should be used in
* the JDA rate-limit handler. Changing this can drastically change the JDA behavior for RestAction execution
* and should be handled carefully. Only change this pool if you know what you're doing.
*
This will override the rate-limit pool provider set from {@link #setRateLimitSchedulerProvider(ThreadPoolProvider)}.
*
*
This is used mostly by the Rate-Limiter to handle backoff delays by using scheduled executions.
* Besides that it is also used by planned execution for {@link net.dv8tion.jda.api.requests.RestAction#queueAfter(long, TimeUnit)}
* and similar methods. Requests are handed off to the {@link #setRateLimitElastic(ExecutorService) elastic pool} for blocking execution.
*
*
Default: Shared {@link ScheduledThreadPoolExecutor} with ({@code 2 * } log({@link #setShardsTotal(int) shard_total})) threads.
*
* @param pool
* The thread-pool to use for rate-limit handling
* @param automaticShutdown
* Whether {@link net.dv8tion.jda.api.JDA#shutdown()} should automatically shutdown this pool
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setRateLimitScheduler(@Nullable ScheduledExecutorService pool, boolean automaticShutdown)
{
return setRateLimitSchedulerProvider(pool == null ? null : new ThreadPoolProviderImpl<>(pool, automaticShutdown));
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} provider that should be used in
* the JDA rate-limit handler. Changing this can drastically change the JDA behavior for RestAction execution
* and should be handled carefully. Only change this pool if you know what you're doing.
*
*
This is used mostly by the Rate-Limiter to handle backoff delays by using scheduled executions.
* Besides that it is also used by planned execution for {@link net.dv8tion.jda.api.requests.RestAction#queueAfter(long, TimeUnit)}
* and similar methods. Requests are handed off to the {@link #setRateLimitElastic(ExecutorService) elastic pool} for blocking execution.
*
*
Default: Shared {@link ScheduledThreadPoolExecutor} with ({@code 2 * } log({@link #setShardsTotal(int) shard_total})) threads.
*
* @param provider
* The thread-pool provider to use for rate-limit handling
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setRateLimitSchedulerProvider(@Nullable ThreadPoolProvider extends ScheduledExecutorService> provider)
{
this.rateLimitSchedulerProvider = provider;
return this;
}
/**
* Sets the {@link ExecutorService} that should be used in
* the JDA request handler. Changing this can drastically change the JDA behavior for RestAction execution
* and should be handled carefully. Only change this pool if you know what you're doing.
*
This will override the rate-limit pool provider set from {@link #setRateLimitElasticProvider(ThreadPoolProvider)}.
*
This automatically disables the automatic shutdown of the rate-limit elastic pool, you can enable
* it using {@link #setRateLimitElastic(ExecutorService, boolean) setRateLimitElastic(executor, true)}
*
*
This is used mostly by the Rate-Limiter to execute the blocking HTTP requests at runtime.
*
*
Default: {@link Executors#newCachedThreadPool()} shared between all shards.
*
* @param pool
* The thread-pool to use for executing http requests
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setRateLimitElastic(@Nullable ExecutorService pool)
{
return setRateLimitElastic(pool, pool == null);
}
/**
* Sets the {@link ExecutorService} that should be used in
* the JDA request handler. Changing this can drastically change the JDA behavior for RestAction execution
* and should be handled carefully. Only change this pool if you know what you're doing.
*
This will override the rate-limit pool provider set from {@link #setRateLimitElasticProvider(ThreadPoolProvider)}.
*
This automatically disables the automatic shutdown of the rate-limit elastic pool, you can enable
* it using {@link #setRateLimitElastic(ExecutorService, boolean) setRateLimitElastic(executor, true)}
*
*
This is used mostly by the Rate-Limiter to execute the blocking HTTP requests at runtime.
*
*
Default: {@link Executors#newCachedThreadPool()} shared between all shards.
*
* @param pool
* The thread-pool to use for executing http requests
* @param automaticShutdown
* Whether {@link net.dv8tion.jda.api.JDA#shutdown()} should automatically shutdown this pool
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setRateLimitElastic(@Nullable ExecutorService pool, boolean automaticShutdown)
{
return setRateLimitElasticProvider(pool == null ? null : new ThreadPoolProviderImpl<>(pool, automaticShutdown));
}
/**
* Sets the {@link ExecutorService} that should be used in
* the JDA request handler. Changing this can drastically change the JDA behavior for RestAction execution
* and should be handled carefully. Only change this pool if you know what you're doing.
*
*
This is used mostly by the Rate-Limiter to execute the blocking HTTP requests at runtime.
*
*
Default: {@link Executors#newCachedThreadPool()} shared between all shards.
*
* @param provider
* The thread-pool provider to use for executing http requests
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setRateLimitElasticProvider(@Nullable ThreadPoolProvider extends ExecutorService> provider)
{
this.rateLimitElasticProvider = provider;
return this;
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} that should be used for
* the JDA main WebSocket workers.
*
Only change this pool if you know what you're doing.
*
This will override the worker pool provider set from {@link #setGatewayPoolProvider(ThreadPoolProvider)}.
*
This automatically disables the automatic shutdown of the main-ws pools, you can enable
* it using {@link #setGatewayPool(ScheduledExecutorService, boolean) setGatewayPoolProvider(pool, true)}
*
*
This is used to send various forms of session updates such as:
*
* - Voice States - (Dis-)Connecting from channels
* - Presence - Changing current activity or online status
* - Guild Setup - Requesting Members of newly joined guilds
* - Heartbeats - Regular updates to keep the connection alive (usually once a minute)
*
* When nothing has to be sent the pool will only be used every 500 milliseconds to check the queue for new payloads.
* Once a new payload is sent we switch to "rapid mode" which means more tasks will be submitted until no more payloads
* have to be sent.
*
* Default: Shared {@link ScheduledThreadPoolExecutor} with ({@code log}({@link #setShardsTotal(int) shard_total})) threads.
*
* @param pool
* The thread-pool to use for main WebSocket workers
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setGatewayPool(@Nullable ScheduledExecutorService pool)
{
return setGatewayPool(pool, pool == null);
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} that should be used for
* the JDA main WebSocket workers.
*
Only change this pool if you know what you're doing.
*
This will override the worker pool provider set from {@link #setGatewayPoolProvider(ThreadPoolProvider)}.
*
*
This is used to send various forms of session updates such as:
*
* - Voice States - (Dis-)Connecting from channels
* - Presence - Changing current activity or online status
* - Guild Setup - Requesting Members of newly joined guilds
* - Heartbeats - Regular updates to keep the connection alive (usually once a minute)
*
* When nothing has to be sent the pool will only be used every 500 milliseconds to check the queue for new payloads.
* Once a new payload is sent we switch to "rapid mode" which means more tasks will be submitted until no more payloads
* have to be sent.
*
* Default: Shared {@link ScheduledThreadPoolExecutor} with ({@code log}({@link #setShardsTotal(int) shard_total})) threads.
*
* @param pool
* The thread-pool to use for main WebSocket workers
* @param automaticShutdown
* Whether {@link net.dv8tion.jda.api.JDA#shutdown()} should automatically shutdown this pool
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setGatewayPool(@Nullable ScheduledExecutorService pool, boolean automaticShutdown)
{
return setGatewayPoolProvider(pool == null ? null : new ThreadPoolProviderImpl<>(pool, automaticShutdown));
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} that should be used for
* the JDA main WebSocket workers.
*
Only change this pool if you know what you're doing.
*
*
This is used to send various forms of session updates such as:
*
* - Voice States - (Dis-)Connecting from channels
* - Presence - Changing current activity or online status
* - Guild Setup - Requesting Members of newly joined guilds
* - Heartbeats - Regular updates to keep the connection alive (usually once a minute)
*
* When nothing has to be sent the pool will only be used every 500 milliseconds to check the queue for new payloads.
* Once a new payload is sent we switch to "rapid mode" which means more tasks will be submitted until no more payloads
* have to be sent.
*
* Default: Shared {@link ScheduledThreadPoolExecutor} with ({@code log}({@link #setShardsTotal(int) shard_total})) threads.
*
* @param provider
* The thread-pool provider to use for main WebSocket workers
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setGatewayPoolProvider(@Nullable ThreadPoolProvider extends ScheduledExecutorService> provider)
{
this.gatewayPoolProvider = provider;
return this;
}
/**
* Sets the {@link ExecutorService ExecutorService} that should be used in
* the JDA callback handler which mostly consists of {@link net.dv8tion.jda.api.requests.RestAction RestAction} callbacks.
* By default JDA will use {@link ForkJoinPool#commonPool()}
*
Only change this pool if you know what you're doing.
*
This automatically disables the automatic shutdown of the callback pools, you can enable
* it using {@link #setCallbackPool(ExecutorService, boolean) setCallbackPool(executor, true)}
*
*
This is used to handle callbacks of {@link RestAction#queue()}, similarly it is used to
* finish {@link RestAction#submit()} and {@link RestAction#complete()} tasks which build on queue.
*
*
Default: {@link ForkJoinPool#commonPool()}
*
* @param executor
* The thread-pool to use for callback handling
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setCallbackPool(@Nullable ExecutorService executor)
{
return setCallbackPool(executor, executor == null);
}
/**
* Sets the {@link ExecutorService ExecutorService} that should be used in
* the JDA callback handler which mostly consists of {@link net.dv8tion.jda.api.requests.RestAction RestAction} callbacks.
* By default JDA will use {@link ForkJoinPool#commonPool()}
*
Only change this pool if you know what you're doing.
*
*
This is used to handle callbacks of {@link RestAction#queue()}, similarly it is used to
* finish {@link RestAction#submit()} and {@link RestAction#complete()} tasks which build on queue.
*
*
Default: {@link ForkJoinPool#commonPool()}
*
* @param executor
* The thread-pool to use for callback handling
* @param automaticShutdown
* Whether {@link net.dv8tion.jda.api.JDA#shutdown()} should automatically shutdown this pool
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setCallbackPool(@Nullable ExecutorService executor, boolean automaticShutdown)
{
return setCallbackPoolProvider(executor == null ? null : new ThreadPoolProviderImpl<>(executor, automaticShutdown));
}
/**
* Sets the {@link ExecutorService ExecutorService} that should be used in
* the JDA callback handler which mostly consists of {@link net.dv8tion.jda.api.requests.RestAction RestAction} callbacks.
* By default JDA will use {@link ForkJoinPool#commonPool()}
*
Only change this pool if you know what you're doing.
*
*
This is used to handle callbacks of {@link RestAction#queue()}, similarly it is used to
* finish {@link RestAction#submit()} and {@link RestAction#complete()} tasks which build on queue.
*
*
Default: {@link ForkJoinPool#commonPool()}
*
* @param provider
* The thread-pool provider to use for callback handling
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setCallbackPoolProvider(@Nullable ThreadPoolProvider extends ExecutorService> provider)
{
this.callbackPoolProvider = provider;
return this;
}
/**
* Sets the {@link ExecutorService ExecutorService} that should be used by the
* event proxy to schedule events. This will be done on the calling thread by default.
*
*
The executor will not be shutdown automatically when the shard is shutdown.
* To shut it down automatically use {@link #setEventPool(ExecutorService, boolean)}.
*
*
Default: Disabled
*
* @param executor
* The executor for the event proxy, or null to use calling thread
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @since 4.2.0
*/
@Nonnull
public DefaultShardManagerBuilder setEventPool(@Nullable ExecutorService executor)
{
return setEventPool(executor, executor == null);
}
/**
* Sets the {@link ExecutorService ExecutorService} that should be used by the
* event proxy to schedule events. This will be done on the calling thread by default.
*
*
Default: Disabled
*
* @param executor
* The executor for the event proxy, or null to use calling thread
* @param automaticShutdown
* True, if the executor should be shutdown when JDA shuts down
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @since 4.2.0
*/
@Nonnull
public DefaultShardManagerBuilder setEventPool(@Nullable ExecutorService executor, boolean automaticShutdown)
{
return setEventPoolProvider(executor == null ? null : new ThreadPoolProviderImpl<>(executor, automaticShutdown));
}
/**
* Sets the {@link ExecutorService ExecutorService} that should be used in
* the JDA callback handler which mostly consists of {@link net.dv8tion.jda.api.requests.RestAction RestAction} callbacks.
* By default JDA will use {@link ForkJoinPool#commonPool()}
*
Only change this pool if you know what you're doing.
*
*
This is used to handle callbacks of {@link RestAction#queue()}, similarly it is used to
* finish {@link RestAction#submit()} and {@link RestAction#complete()} tasks which build on queue.
*
*
Default: Disabled
*
* @param provider
* The thread-pool provider to use for callback handling
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @since 4.2.0
*/
@Nonnull
public DefaultShardManagerBuilder setEventPoolProvider(@Nullable ThreadPoolProvider extends ExecutorService> provider)
{
this.eventPoolProvider = provider;
return this;
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} used by
* the audio WebSocket connection. Used for sending keepalives and closing the connection.
*
Only change this pool if you know what you're doing.
*
*
Default: {@link ScheduledThreadPoolExecutor} with 1 thread
*
* @param pool
* The thread-pool to use for the audio WebSocket
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @since 4.2.1
*/
@Nonnull
public DefaultShardManagerBuilder setAudioPool(@Nullable ScheduledExecutorService pool)
{
return setAudioPool(pool, pool == null);
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} used by
* the audio WebSocket connection. Used for sending keepalives and closing the connection.
*
Only change this pool if you know what you're doing.
*
*
Default: {@link ScheduledThreadPoolExecutor} with 1 thread
*
* @param pool
* The thread-pool to use for the audio WebSocket
* @param automaticShutdown
* True, if the executor should be shutdown when JDA shuts down
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @since 4.2.1
*/
@Nonnull
public DefaultShardManagerBuilder setAudioPool(@Nullable ScheduledExecutorService pool, boolean automaticShutdown)
{
return setAudioPoolProvider(pool == null ? null : new ThreadPoolProviderImpl<>(pool, automaticShutdown));
}
/**
* Sets the {@link ScheduledExecutorService ScheduledExecutorService} used by
* the audio WebSocket connection. Used for sending keepalives and closing the connection.
*
Only change this pool if you know what you're doing.
*
*
Default: {@link ScheduledThreadPoolExecutor} with 1 thread
*
* @param provider
* The thread-pool provider to use for the audio WebSocket
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @since 4.2.1
*/
@Nonnull
public DefaultShardManagerBuilder setAudioPoolProvider(@Nullable ThreadPoolProvider extends ScheduledExecutorService> provider)
{
this.audioPoolProvider = provider;
return this;
}
/**
* Sets the maximum amount of time that JDA will back off to wait when attempting to reconnect the MainWebsocket.
*
Provided value must be 32 or greater.
*
*
Default: {@code 900}
*
* @param maxReconnectDelay
* The maximum amount of time that JDA will wait between reconnect attempts in seconds.
*
* @throws java.lang.IllegalArgumentException
* Thrown if the provided {@code maxReconnectDelay} is less than 32.
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setMaxReconnectDelay(final int maxReconnectDelay)
{
Checks.check(maxReconnectDelay >= 32, "Max reconnect delay must be 32 seconds or greater. You provided %d.", maxReconnectDelay);
this.maxReconnectDelay = maxReconnectDelay;
return this;
}
/**
* Whether the Requester should retry when
* a {@link java.net.SocketTimeoutException SocketTimeoutException} occurs.
*
Default: {@code true}
*
*
This value can be changed at any time with {@link net.dv8tion.jda.api.JDA#setRequestTimeoutRetry(boolean) JDA.setRequestTimeoutRetry(boolean)}!
*
* @param retryOnTimeout
* True, if the Request should retry once on a socket timeout
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setRequestTimeoutRetry(boolean retryOnTimeout)
{
return setFlag(ConfigFlag.RETRY_TIMEOUT, retryOnTimeout);
}
/**
* Sets the list of shards the {@link DefaultShardManager DefaultShardManager} should contain.
*
*
This does not have any effect if the total shard count is set to {@code -1} (get recommended shards from discord).
*
* @param shardIds
* The list of shard ids
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setShards(final int... shardIds)
{
Checks.notNull(shardIds, "shardIds");
for (int id : shardIds)
{
Checks.notNegative(id, "minShardId");
Checks.check(id < this.shardsTotal, "maxShardId must be lower than shardsTotal");
}
this.shards = Arrays.stream(shardIds).boxed().collect(Collectors.toSet());
return this;
}
/**
* Sets the range of shards the {@link DefaultShardManager DefaultShardManager} should contain.
* This is useful if you want to split your shards between multiple JVMs or servers.
*
*
This does not have any effect if the total shard count is set to {@code -1} (get recommended shards from discord).
*
* @param minShardId
* The lowest shard id the DefaultShardManager should contain
*
* @param maxShardId
* The highest shard id the DefaultShardManager should contain
*
* @throws IllegalArgumentException
* If either minShardId is negative, maxShardId is lower than shardsTotal or
* minShardId is lower than or equal to maxShardId
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setShards(final int minShardId, final int maxShardId)
{
Checks.notNegative(minShardId, "minShardId");
Checks.check(maxShardId < this.shardsTotal, "maxShardId must be lower than shardsTotal");
Checks.check(minShardId <= maxShardId, "minShardId must be lower than or equal to maxShardId");
List shards = new ArrayList<>(maxShardId - minShardId + 1);
for (int i = minShardId; i <= maxShardId; i++)
shards.add(i);
this.shards = shards;
return this;
}
/**
* Sets the range of shards the {@link DefaultShardManager DefaultShardManager} should contain.
* This is useful if you want to split your shards between multiple JVMs or servers.
*
* This does not have any effect if the total shard count is set to {@code -1} (get recommended shards from discord).
*
* @param shardIds
* The list of shard ids
*
* @throws IllegalArgumentException
* If either minShardId is negative, maxShardId is lower than shardsTotal or
* minShardId is lower than or equal to maxShardId
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setShards(@Nonnull Collection shardIds)
{
Checks.notNull(shardIds, "shardIds");
for (Integer id : shardIds)
{
Checks.notNegative(id, "minShardId");
Checks.check(id < this.shardsTotal, "maxShardId must be lower than shardsTotal");
}
this.shards = new ArrayList<>(shardIds);
return this;
}
/**
* This will set the total amount of shards the {@link DefaultShardManager DefaultShardManager} should use.
* If this is set to {@code -1} JDA will automatically retrieve the recommended amount of shards from discord (default behavior).
*
* @param shardsTotal
* The number of overall shards or {@code -1} if JDA should use the recommended amount from discord.
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #setShards(int, int)
*/
@Nonnull
public DefaultShardManagerBuilder setShardsTotal(final int shardsTotal)
{
Checks.check(shardsTotal == -1 || shardsTotal > 0, "shardsTotal must either be -1 or greater than 0");
this.shardsTotal = shardsTotal;
return this;
}
/**
* Sets the token that will be used by the {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} instance to log in when
* {@link net.dv8tion.jda.api.sharding.DefaultShardManagerBuilder#build() build()} is called.
*
*
To get a bot token:
*
* - Go to your Discord Applications
* - Create or select an already existing application
* - Verify that it has already been turned into a Bot. If you see the "Create a Bot User" button, click it.
* - Click the click to reveal link beside the Token label to show your Bot's {@code token}
*
*
* @param token
* The token of the account that you would like to login with.
*
* @throws java.lang.IllegalArgumentException
* If the token is either null or empty
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setToken(@Nonnull final String token)
{
Checks.notBlank(token, "token");
this.token = token;
return this;
}
/**
* Whether the {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} should use
* {@link net.dv8tion.jda.api.JDA#shutdownNow() JDA#shutdownNow()} instead of
* {@link net.dv8tion.jda.api.JDA#shutdown() JDA#shutdown()} to shutdown it's shards.
*
Default: {@code false}
*
* @param useShutdownNow
* Whether the ShardManager should use JDA#shutdown() or not
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see net.dv8tion.jda.api.JDA#shutdown()
* @see net.dv8tion.jda.api.JDA#shutdownNow()
*/
@Nonnull
public DefaultShardManagerBuilder setUseShutdownNow(final boolean useShutdownNow)
{
return setFlag(ShardingConfigFlag.SHUTDOWN_NOW, useShutdownNow);
}
/**
* Sets the {@link com.neovisionaries.ws.client.WebSocketFactory WebSocketFactory} that will be used by JDA's websocket client.
* This can be used to set things such as connection timeout and proxy.
*
* @param factory
* The new {@link com.neovisionaries.ws.client.WebSocketFactory WebSocketFactory} to use.
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setWebsocketFactory(@Nullable WebSocketFactory factory)
{
this.wsFactory = factory;
return this;
}
/**
* The {@link ChunkingFilter} to filter which guilds should use member chunking.
*
* Use {@link #setMemberCachePolicy(MemberCachePolicy)} to configure which members to keep in cache from chunking.
*
* @param filter
* The filter to apply
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @since 4.0.0
*
* @see ChunkingFilter#NONE
* @see ChunkingFilter#include(long...)
* @see ChunkingFilter#exclude(long...)
*/
@Nonnull
public DefaultShardManagerBuilder setChunkingFilter(@Nullable ChunkingFilter filter)
{
this.chunkingFilter = filter;
return this;
}
/**
* Configures which events will be disabled.
* Bots which did not enable presence/member updates in the developer dashboard are required to disable {@link GatewayIntent#GUILD_PRESENCES} and {@link GatewayIntent#GUILD_MEMBERS}!
*
*
It is not recommended to disable {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} when
* using {@link MemberCachePolicy#ALL MemberCachePolicy.ALL} as the members cannot be removed from cache by a leave event without this intent.
*
*
If you disable certain intents you also have to disable related {@link CacheFlag CacheFlags}.
* This can be achieved using {@link #disableCache(CacheFlag, CacheFlag...)}. The required intents for each
* flag are documented in the {@link CacheFlag} enum.
*
* @param intent
* The first intent to disable
* @param intents
* Any other intents to disable
*
* @throws IllegalArgumentException
* If null is provided
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #setMemberCachePolicy(MemberCachePolicy)
*
* @since 4.2.0
*/
@Nonnull
public DefaultShardManagerBuilder setDisabledIntents(@Nonnull GatewayIntent intent, @Nonnull GatewayIntent... intents)
{
Checks.notNull(intent, "Intent");
Checks.noneNull(intents, "Intent");
EnumSet set = EnumSet.of(intent, intents);
return setDisabledIntents(set);
}
/**
* Configures which events will be disabled.
* Bots which did not enable presence/member updates in the developer dashboard are required to disable {@link GatewayIntent#GUILD_PRESENCES} and {@link GatewayIntent#GUILD_MEMBERS}!
*
* It is not recommended to disable {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} when
* using {@link MemberCachePolicy#ALL MemberCachePolicy.ALL} as the members cannot be removed from cache by a leave event without this intent.
*
*
If you disable certain intents you also have to disable related {@link CacheFlag CacheFlags}.
* This can be achieved using {@link #disableCache(CacheFlag, CacheFlag...)}. The required intents for each
* flag are documented in the {@link CacheFlag} enum.
*
* @param intents
* The intents to disable, or null to disable all intents (default: none)
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #setMemberCachePolicy(MemberCachePolicy)
*
* @since 4.2.0
*/
@Nonnull
public DefaultShardManagerBuilder setDisabledIntents(@Nullable Collection intents)
{
this.intents = GatewayIntent.ALL_INTENTS;
if (intents != null)
this.intents = 1 | ~GatewayIntent.getRaw(intents);
return this;
}
/**
* Disable the specified {@link GatewayIntent GatewayIntents}.
*
This will not enable any currently unset intents.
*
* If you disable certain intents you also have to disable related {@link CacheFlag CacheFlags}.
* This can be achieved using {@link #disableCache(CacheFlag, CacheFlag...)}. The required intents for each
* flag are documented in the {@link CacheFlag} enum.
*
* @param intents
* The intents to disable
*
* @throws IllegalArgumentException
* If provided with null
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #enableIntents(Collection)
*/
@Nonnull
public DefaultShardManagerBuilder disableIntents(@Nonnull Collection intents)
{
Checks.noneNull(intents, "GatewayIntent");
int raw = GatewayIntent.getRaw(intents);
this.intents &= ~raw;
return this;
}
/**
* Disable the specified {@link GatewayIntent GatewayIntents}.
*
This will not enable any currently unset intents.
*
* If you disable certain intents you also have to disable related {@link CacheFlag CacheFlags}.
* This can be achieved using {@link #disableCache(CacheFlag, CacheFlag...)}. The required intents for each
* flag are documented in the {@link CacheFlag} enum.
*
* @param intent
* The intent to disable
* @param intents
* Other intents to disable
*
* @throws IllegalArgumentException
* If provided with null
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #enableIntents(GatewayIntent, GatewayIntent...)
*/
@Nonnull
public DefaultShardManagerBuilder disableIntents(@Nonnull GatewayIntent intent, @Nonnull GatewayIntent... intents)
{
Checks.notNull(intent, "GatewayIntent");
Checks.noneNull(intents, "GatewayIntent");
int raw = GatewayIntent.getRaw(intent, intents);
this.intents &= ~raw;
return this;
}
/**
* Configures which events will be enabled.
* Bots which did not enable presence/member updates in the developer dashboard are required to disable {@link GatewayIntent#GUILD_PRESENCES} and {@link GatewayIntent#GUILD_MEMBERS}!
*
*
It is not recommended to disable {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} when
* using {@link MemberCachePolicy#ALL MemberCachePolicy.ALL} as the members cannot be removed from cache by a leave event without this intent.
*
*
If you disable certain intents you also have to disable related {@link CacheFlag CacheFlags}.
* This can be achieved using {@link #disableCache(CacheFlag, CacheFlag...)}. The required intents for each
* flag are documented in the {@link CacheFlag} enum.
*
* @param intent
* The intent to enable
* @param intents
* Any other intents to enable
*
* @throws IllegalArgumentException
* If null is provided
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #setMemberCachePolicy(MemberCachePolicy)
*
* @since 4.2.0
*/
@Nonnull
public DefaultShardManagerBuilder setEnabledIntents(@Nonnull GatewayIntent intent, @Nonnull GatewayIntent... intents)
{
Checks.notNull(intent, "Intent");
Checks.noneNull(intents, "Intent");
EnumSet set = EnumSet.of(intent, intents);
return setEnabledIntents(set);
}
/**
* Configures which events will be enabled.
* Bots which did not enable presence/member updates in the developer dashboard are required to disable {@link GatewayIntent#GUILD_PRESENCES} and {@link GatewayIntent#GUILD_MEMBERS}!
*
* It is not recommended to disable {@link GatewayIntent#GUILD_MEMBERS GatewayIntent.GUILD_MEMBERS} when
* using {@link MemberCachePolicy#ALL MemberCachePolicy.ALL} as the members cannot be removed from cache by a leave event without this intent.
*
*
If you disable certain intents you also have to disable related {@link CacheFlag CacheFlags}.
* This can be achieved using {@link #disableCache(CacheFlag, CacheFlag...)}. The required intents for each
* flag are documented in the {@link CacheFlag} enum.
*
* @param intents
* The intents to enable, or null to enable no intents (default: all)
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #setMemberCachePolicy(MemberCachePolicy)
*
* @since 4.2.0
*/
@Nonnull
public DefaultShardManagerBuilder setEnabledIntents(@Nullable Collection intents)
{
if (intents == null || intents.isEmpty())
this.intents = 1;
else
this.intents = 1 | GatewayIntent.getRaw(intents);
return this;
}
/**
* Enable the specified {@link GatewayIntent GatewayIntents}.
*
This will not disable any currently set intents.
*
* @param intents
* The intents to enable
*
* @throws IllegalArgumentException
* If provided with null
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #disableIntents(Collection)
*/
@Nonnull
public DefaultShardManagerBuilder enableIntents(@Nonnull Collection intents)
{
Checks.noneNull(intents, "GatewayIntent");
int raw = GatewayIntent.getRaw(intents);
this.intents |= raw;
return this;
}
/**
* Enable the specified {@link GatewayIntent GatewayIntents}.
*
This will not disable any currently set intents.
*
* @param intent
* The intent to enable
* @param intents
* Other intents to enable
*
* @throws IllegalArgumentException
* If provided with null
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @see #enableIntents(GatewayIntent, GatewayIntent...)
*/
@Nonnull
public DefaultShardManagerBuilder enableIntents(@Nonnull GatewayIntent intent, @Nonnull GatewayIntent... intents)
{
Checks.notNull(intent, "GatewayIntent");
Checks.noneNull(intents, "GatewayIntent");
int raw = GatewayIntent.getRaw(intent, intents);
this.intents |= raw;
return this;
}
/**
* Decides the total number of members at which a guild should start to use lazy loading.
*
This is limited to a number between 50 and 250 (inclusive).
* If the {@link #setChunkingFilter(ChunkingFilter) chunking filter} is set to {@link ChunkingFilter#ALL}
* this should be set to {@code 250} (default) to minimize the amount of guilds that need to request members.
*
* @param threshold
* The threshold in {@code [50, 250]}
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*
* @since 4.0.0
*/
@Nonnull
public DefaultShardManagerBuilder setLargeThreshold(int threshold)
{
this.largeThreshold = Math.max(50, Math.min(250, threshold)); // enforce 50 <= t <= 250
return this;
}
/**
* The maximum size, in bytes, of the buffer used for decompressing discord payloads.
*
If the maximum buffer size is exceeded a new buffer will be allocated instead.
*
Setting this to {@link Integer#MAX_VALUE} would imply the buffer will never be resized unless memory starvation is imminent.
*
Setting this to {@code 0} would imply the buffer would need to be allocated again for every payload (not recommended).
*
* Default: {@code 2048}
*
* @param bufferSize
* The maximum size the buffer should allow to retain
*
* @throws IllegalArgumentException
* If the provided buffer size is negative
*
* @return The DefaultShardManagerBuilder instance. Useful for chaining.
*/
@Nonnull
public DefaultShardManagerBuilder setMaxBufferSize(int bufferSize)
{
Checks.notNegative(bufferSize, "The buffer size");
this.maxBufferSize = bufferSize;
return this;
}
/**
* Builds a new {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} instance and uses the provided token to start the login process.
*
The login process runs in a different thread, so while this will return immediately, {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} has not
* finished loading, thus many {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} methods have the chance to return incorrect information.
*
The main use of this method is to start the JDA connect process and do other things in parallel while startup is
* being performed like database connection or local resource loading.
*
*
Note that this method is async and as such will not block until all shards are started.
*
* @throws InvalidTokenException
* If the provided token is invalid.
* @throws IllegalArgumentException
* If the provided token is empty or null. Or the provided intents/cache configuration is not possible.
* @throws net.dv8tion.jda.api.exceptions.ErrorResponseException
* If some other HTTP error occurred.
*
* @return A {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} instance that has started the login process. It is unknown as
* to whether or not loading has finished when this returns.
*/
@Nonnull
public ShardManager build() throws IllegalArgumentException
{
return build(true);
}
/**
* Builds a new {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} instance. If the login parameter is true, then it will start the login process.
*
The login process runs in a different thread, so while this will return immediately, {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} has not
* finished loading, thus many {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} methods have the chance to return incorrect information.
*
The main use of this method is to start the JDA connect process and do other things in parallel while startup is
* being performed like database connection or local resource loading.
*
*
Note that this method is async and as such will not block until all shards are started.
*
* @param login
* Whether the login process will be started. If this is false, then you will need to manually call
* {@link net.dv8tion.jda.api.sharding.ShardManager#login()} to start it.
*
* @throws InvalidTokenException
* If the provided token is invalid and {@code login} is true
* @throws IllegalArgumentException
* If the provided token is empty or null. Or the provided intents/cache configuration is not possible.
*
* @return A {@link net.dv8tion.jda.api.sharding.ShardManager ShardManager} instance. If {@code login} is set to
* true, then the instance will have started the login process. It is unknown as to whether or not loading has
* finished when this returns.
*/
@Nonnull
public ShardManager build(boolean login) throws IllegalArgumentException
{
checkIntents();
boolean useShutdownNow = shardingFlags.contains(ShardingConfigFlag.SHUTDOWN_NOW);
final ShardingConfig shardingConfig = new ShardingConfig(shardsTotal, useShutdownNow, intents, memberCachePolicy);
final EventConfig eventConfig = new EventConfig(eventManagerProvider);
listeners.forEach(eventConfig::addEventListener);
listenerProviders.forEach(eventConfig::addEventListenerProvider);
final PresenceProviderConfig presenceConfig = new PresenceProviderConfig();
presenceConfig.setActivityProvider(activityProvider);
presenceConfig.setStatusProvider(statusProvider);
presenceConfig.setIdleProvider(idleProvider);
final ThreadingProviderConfig threadingConfig = new ThreadingProviderConfig(rateLimitSchedulerProvider, rateLimitElasticProvider, gatewayPoolProvider, callbackPoolProvider, eventPoolProvider, audioPoolProvider, threadFactory);
final ShardingSessionConfig sessionConfig = new ShardingSessionConfig(sessionController, voiceDispatchInterceptor, httpClient, httpClientBuilder, wsFactory, audioSendFactory, flags, shardingFlags, maxReconnectDelay, largeThreshold);
final ShardingMetaConfig metaConfig = new ShardingMetaConfig(maxBufferSize, contextProvider, cacheFlags, flags, compression, encoding);
final DefaultShardManager manager = new DefaultShardManager(this.token, this.shards, shardingConfig, eventConfig, presenceConfig, threadingConfig, sessionConfig, metaConfig, restConfigProvider, chunkingFilter);
if (login)
manager.login();
return manager;
}
private DefaultShardManagerBuilder setFlag(ConfigFlag flag, boolean enable)
{
if (enable)
this.flags.add(flag);
else
this.flags.remove(flag);
return this;
}
private DefaultShardManagerBuilder setFlag(ShardingConfigFlag flag, boolean enable)
{
if (enable)
this.shardingFlags.add(flag);
else
this.shardingFlags.remove(flag);
return this;
}
private void checkIntents()
{
boolean membersIntent = (intents & GatewayIntent.GUILD_MEMBERS.getRawValue()) != 0;
if (!membersIntent && memberCachePolicy == MemberCachePolicy.ALL)
throw new IllegalStateException("Cannot use MemberCachePolicy.ALL without GatewayIntent.GUILD_MEMBERS enabled!");
else if (!membersIntent && chunkingFilter != ChunkingFilter.NONE)
DefaultShardManager.LOG.warn("Member chunking is disabled due to missing GUILD_MEMBERS intent.");
if (!automaticallyDisabled.isEmpty())
{
JDAImpl.LOG.warn("Automatically disabled CacheFlags due to missing intents");
// List each missing intent
automaticallyDisabled.stream()
.map(it -> "Disabled CacheFlag." + it + " (missing GatewayIntent." + it.getRequiredIntent() + ")")
.forEach(JDAImpl.LOG::warn);
// Tell user how to disable this warning
JDAImpl.LOG.warn("You can manually disable these flags to remove this warning by using disableCache({}) on your DefaultShardManagerBuilder",
automaticallyDisabled.stream()
.map(it -> "CacheFlag." + it)
.collect(Collectors.joining(", ")));
// Only print this warning once
automaticallyDisabled.clear();
}
if (cacheFlags.isEmpty())
return;
EnumSet providedIntents = GatewayIntent.getIntents(intents);
for (CacheFlag flag : cacheFlags)
{
GatewayIntent intent = flag.getRequiredIntent();
if (intent != null && !providedIntents.contains(intent))
throw new IllegalArgumentException("Cannot use CacheFlag." + flag + " without GatewayIntent." + intent + "!");
}
}
//Avoid having multiple anonymous classes
private static class ThreadPoolProviderImpl implements ThreadPoolProvider
{
private final boolean autoShutdown;
private final T pool;
public ThreadPoolProviderImpl(T pool, boolean autoShutdown)
{
this.autoShutdown = autoShutdown;
this.pool = pool;
}
@Override
public T provide(int shardId)
{
return pool;
}
@Override
public boolean shouldShutdownAutomatically(int shardId)
{
return autoShutdown;
}
}
}