Skip to content

Commit

Permalink
Merge pull request #654 from DV8FromTheWorld/release/3.6.0
Browse files Browse the repository at this point in the history
Release 3.6.0
  • Loading branch information
MinnDevelopment authored Mar 28, 2018
2 parents 3b5687d + 7e4839a commit 3092875
Show file tree
Hide file tree
Showing 259 changed files with 6,749 additions and 2,259 deletions.
7 changes: 4 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ plugins {
id 'com.github.johnrengelman.shadow' version '2.0.1'
}

def versionObj = new Version(major: 3, minor: 5, revision: 1)
def versionObj = new Version(major: 3, minor: 6, revision: 0)

group = "net.dv8tion"
archivesBaseName = "JDA"
Expand Down Expand Up @@ -83,12 +83,13 @@ task sourcesForRelease(type: Copy) {
])
}


compileJava {
options.compilerArgs += ["-Xlint:deprecation", "-Xlint:unchecked"]
options.encoding = 'UTF-8'
source = sourcesForRelease.destinationDir
classpath = sourceSets.main.compileClasspath

options.encoding = 'UTF-8'

dependsOn sourcesForRelease
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ public class DefaultShardManager implements ShardManager
*/
protected final List<Object> listeners;

/**
* The event listener providers for new and restarted JDA instances.
*/
protected final List<IntFunction<Object>> listenerProviders;

/**
* The maximum amount of time that JDA will back off to wait when attempting to reconnect the MainWebsocket.
*/
Expand Down Expand Up @@ -201,6 +206,11 @@ public class DefaultShardManager implements ShardManager
*/
protected boolean enableMDC;

/**
* Whether to enable transport compression
*/
protected boolean enableCompression;

/**
* Creates a new DefaultShardManager instance.
* @param shardsTotal
Expand All @@ -212,6 +222,9 @@ public class DefaultShardManager implements ShardManager
* The {@link net.dv8tion.jda.core.utils.SessionController SessionController}
* @param listeners
* The event listeners for new JDA instances.
* @param listenerProviders
* Providers of event listeners for JDA instances. Each will have the shard id applied to them upon
* shard creation (including shard restarts) and must return an event listener
* @param token
* The token
* @param eventManager
Expand Down Expand Up @@ -251,9 +264,12 @@ public class DefaultShardManager implements ShardManager
* Whether MDC should be enabled
* @param contextProvider
* The MDC context provider new JDA instances should use on startup
* @param enableCompression
* Whether to enable transport compression
*/
protected DefaultShardManager(final int shardsTotal, final Collection<Integer> shardIds,
final SessionController controller, final List<Object> listeners,
final List<IntFunction<Object>> listenerProviders,
final String token, final IEventManager eventManager, final IAudioSendFactory audioSendFactory,
final IntFunction<Game> gameProvider, final IntFunction<OnlineStatus> statusProvider,
final OkHttpClient.Builder httpClientBuilder, final WebSocketFactory wsFactory,
Expand All @@ -262,10 +278,12 @@ protected DefaultShardManager(final int shardsTotal, final Collection<Integer> s
final boolean enableShutdownHook, final boolean enableBulkDeleteSplitting,
final boolean autoReconnect, final IntFunction<Boolean> idleProvider,
final boolean retryOnTimeout, final boolean useShutdownNow,
final boolean enableMDC, final IntFunction<ConcurrentMap<String, String>> contextProvider)
final boolean enableMDC, final IntFunction<ConcurrentMap<String, String>> contextProvider,
final boolean enableCompression)
{
this.shardsTotal = shardsTotal;
this.listeners = listeners;
this.listenerProviders = listenerProviders;
this.token = token;
this.eventManager = eventManager;
this.audioSendFactory = audioSendFactory;
Expand All @@ -286,6 +304,7 @@ protected DefaultShardManager(final int shardsTotal, final Collection<Integer> s
this.useShutdownNow = useShutdownNow;
this.contextProvider = contextProvider;
this.enableMDC = enableMDC;
this.enableCompression = enableCompression;

synchronized (queue)
{
Expand Down Expand Up @@ -320,6 +339,19 @@ public void removeEventListener(final Object... listeners)
this.listeners.removeAll(Arrays.asList(listeners));
}

@Override
public void addEventListeners(IntFunction<Object> eventListenerProvider)
{
ShardManager.super.addEventListeners(eventListenerProvider);
this.listenerProviders.add(eventListenerProvider);
}

@Override
public void removeEventListenerProvider(IntFunction<Object> eventListenerProvider)
{
this.listenerProviders.remove(eventListenerProvider);
}

@Override
public int getShardsQueued()
{
Expand Down Expand Up @@ -557,6 +589,7 @@ protected JDAImpl buildInstance(final int shardId) throws LoginException, Interr
jda.setAudioSendFactory(this.audioSendFactory);

this.listeners.forEach(jda::addEventListener);
this.listenerProviders.forEach(provider -> jda.addEventListener(provider.apply(shardId)));
jda.setStatus(JDA.Status.INITIALIZED); //This is already set by JDA internally, but this is to make sure the listeners catch it.

// Set the presence information before connecting to have the correct information ready when sending IDENTIFY
Expand Down Expand Up @@ -602,7 +635,7 @@ protected JDAImpl buildInstance(final int shardId) throws LoginException, Interr

final JDA.ShardInfo shardInfo = new JDA.ShardInfo(shardId, this.shardsTotal);

final int shardTotal = jda.login(this.gatewayURL, shardInfo);
final int shardTotal = jda.login(this.gatewayURL, shardInfo, this.enableCompression);
if (this.shardsTotal == -1)
this.shardsTotal = shardTotal;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@
import okhttp3.OkHttpClient;

import javax.security.auth.login.LoginException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ThreadFactory;
import java.util.function.IntFunction;
Expand All @@ -46,6 +43,7 @@
public class DefaultShardManagerBuilder
{
protected final List<Object> listeners = new ArrayList<>();
protected final List<IntFunction<Object>> listenerProviders = new ArrayList<>();
protected SessionController sessionController = null;
protected IntFunction<ConcurrentMap<String, String>> contextProvider = null;
protected boolean enableContext = true;
Expand All @@ -55,6 +53,7 @@ public class DefaultShardManagerBuilder
protected boolean autoReconnect = true;
protected boolean retryOnTimeout = true;
protected boolean useShutdownNow = false;
protected boolean enableCompression = true;
protected int shardsTotal = -1;
protected int maxReconnectDelay = 900;
protected int corePoolSize = 2;
Expand Down Expand Up @@ -138,6 +137,28 @@ public DefaultShardManagerBuilder setContextEnabled(boolean enable)
return this;
}

/**
* Enable stream-compression on the gateway connection,
* this will decrease the amount of used bandwidth for the running bot instance
* for the cost of a few extra cycles for decompression.
* <br><b>Default: true</b>
*
* <p><b>We recommend to keep this enabled unless you have issues with the decompression</b>
* <br>This mode might become obligatory in a future version, do not rely on this switch to stay.
*
* @param enable
* True, if the gateway connection should use compression
*
* @return The {@link net.dv8tion.jda.bot.sharding.DefaultShardManagerBuilder DefaultShardManagerBuilder} instance. Useful for chaining.
*
* @see <a href="https://discordapp.com/developers/docs/topics/gateway#transport-compression" target="_blank">Official Discord Documentation - Transport Compression</a>
*/
public DefaultShardManagerBuilder setCompressionEnabled(boolean enable)
{
this.enableCompression = enable;
return this;
}

/**
* Adds all provided listeners to the list of listeners that will be used to populate the {@link DefaultShardManager DefaultShardManager} object.
* <br>This uses the {@link net.dv8tion.jda.core.hooks.InterfacedEventManager InterfacedEventListener} by default.
Expand Down Expand Up @@ -216,6 +237,82 @@ public DefaultShardManagerBuilder removeEventListeners(final Collection<Object>
return this;
}

/**
* Adds the provided listener provider to the list of listener providers that will be used to create listeners.
* On shard creation (including shard restarts) the provider will have the shard id applied and must return a listener,
* which will be used, along all other listeners, to populate the listeners of the JDA object of that shard.
*
* <br>This uses the {@link net.dv8tion.jda.core.hooks.InterfacedEventManager InterfacedEventListener} by default.
* <br>To switch to the {@link net.dv8tion.jda.core.hooks.AnnotatedEventManager AnnotatedEventManager},
* use {@link #setEventManager(net.dv8tion.jda.core.hooks.IEventManager) setEventManager(new AnnotatedEventManager())}.
*
* <p><b>Note:</b> When using the {@link net.dv8tion.jda.core.hooks.InterfacedEventManager InterfacedEventListener} (default),
* given listener(s) <b>must</b> be instance of {@link net.dv8tion.jda.core.hooks.EventListener EventListener}!
*
* @param listenerProvider
* The listener provider to add to the list of listener providers.
*
* @return The {@link net.dv8tion.jda.bot.sharding.DefaultShardManagerBuilder DefaultShardManagerBuilder} instance. Useful for chaining.
*/
public DefaultShardManagerBuilder addEventListenerProvider(final IntFunction<Object> listenerProvider)
{
return this.addEventListenerProviders(Collections.singleton(listenerProvider));
}

/**
* Adds the provided listener providers to the list of listener providers that will be used to create listeners.
* On shard creation (including shard restarts) each provider will have the shard id applied and must return a listener,
* which will be used, along all other listeners, to populate the listeners of the JDA object of that shard.
*
* <br>This uses the {@link net.dv8tion.jda.core.hooks.InterfacedEventManager InterfacedEventListener} by default.
* <br>To switch to the {@link net.dv8tion.jda.core.hooks.AnnotatedEventManager AnnotatedEventManager},
* use {@link #setEventManager(net.dv8tion.jda.core.hooks.IEventManager) setEventManager(new AnnotatedEventManager())}.
*
* <p><b>Note:</b> When using the {@link net.dv8tion.jda.core.hooks.InterfacedEventManager InterfacedEventListener} (default),
* given listener(s) <b>must</b> be instance of {@link net.dv8tion.jda.core.hooks.EventListener EventListener}!
*
* @param listenerProviders
* The listener provider to add to the list of listener providers.
*
* @return The {@link net.dv8tion.jda.bot.sharding.DefaultShardManagerBuilder DefaultShardManagerBuilder} instance. Useful for chaining.
*/
public DefaultShardManagerBuilder addEventListenerProviders(final Collection<IntFunction<Object>> listenerProviders)
{
Checks.noneNull(listenerProviders, "listener providers");

this.listenerProviders.addAll(listenerProviders);
return this;
}

/**
* Removes the provided listener provider from the list of listener providers.
*
* @param listenerProvider
* The listener provider to remove from the list of listener providers.
*
* @return The {@link net.dv8tion.jda.bot.sharding.DefaultShardManagerBuilder DefaultShardManagerBuilder} instance. Useful for chaining.
*/
public DefaultShardManagerBuilder removeEventListenerProvider(final IntFunction<Object> listenerProvider)
{
return this.removeEventListenerProviders(Collections.singleton(listenerProvider));
}

/**
* Removes all provided listener providers from the list of listener providers.
*
* @param listenerProviders
* The listener provider(s) to remove from the list of listener providers.
*
* @return The {@link net.dv8tion.jda.bot.sharding.DefaultShardManagerBuilder DefaultShardManagerBuilder} instance. Useful for chaining.
*/
public DefaultShardManagerBuilder removeEventListenerProviders(final Collection<IntFunction<Object>> listenerProviders)
{
Checks.noneNull(listenerProviders, "listener providers");

this.listenerProviders.removeAll(listenerProviders);
return this;
}

/**
* Enables/Disables Voice functionality.
* <br>This is useful, if your current system doesn't support Voice and you do not need it.
Expand Down Expand Up @@ -731,11 +828,11 @@ public ShardManager build() throws LoginException, IllegalArgumentException
{
final DefaultShardManager manager = new DefaultShardManager(
this.shardsTotal, this.shards, this.sessionController,
this.listeners, this.token, this.eventManager,
this.listeners, this.listenerProviders, this.token, this.eventManager,
this.audioSendFactory, this.gameProvider, this.statusProvider,
this.httpClientBuilder, this.wsFactory, this.threadFactory,
this.maxReconnectDelay, this.corePoolSize, this.enableVoice, this.enableShutdownHook, this.enableBulkDeleteSplitting,
this.autoReconnect, this.idleProvider, this.retryOnTimeout, this.useShutdownNow, this.enableContext, this.contextProvider);
this.autoReconnect, this.idleProvider, this.retryOnTimeout, this.useShutdownNow, this.enableContext, this.contextProvider, this.enableCompression);

manager.login();

Expand Down
60 changes: 60 additions & 0 deletions src/main/java/net/dv8tion/jda/bot/sharding/ShardManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,66 @@ default void removeEventListener(final Object... listeners)
this.getShardCache().forEach(jda -> jda.removeEventListener(listeners));
}

/**
* Adds listeners provided by the listener provider to each shard to the event-listeners that will be used to handle events.
* The listener provider gets a shard id applied and is expected to return a listener.
*
* <p>Note: when using the {@link net.dv8tion.jda.core.hooks.InterfacedEventManager InterfacedEventListener} (default),
* given listener <b>must</b> be instance of {@link net.dv8tion.jda.core.hooks.EventListener EventListener}!
*
* @param eventListenerProvider
* The provider of listener(s) which will react to events.
*
* @throws java.lang.IllegalArgumentException
* If the provided listener provider or any of the listeners or provides are {@code null}.
*/
default void addEventListeners(final IntFunction<Object> eventListenerProvider)
{
Checks.notNull(eventListenerProvider, "event listener provider");
this.getShardCache().forEach(jda ->
{
Object listener = eventListenerProvider.apply(jda.getShardInfo().getShardId());
if (listener != null) jda.addEventListener(listener);
});
}

/**
* Remove listeners from shards by their id.
* The provider takes shard ids, and returns a collection of listeners that shall be removed from the respective
* shards.
*
* @param eventListenerProvider
* gets shard ids applied and is expected to return a collection of listeners that shall be removed from
* the respective shards
*
* @throws java.lang.IllegalArgumentException
* If the provided event listeners provider is {@code null}.
*/
default void removeEventListeners(final IntFunction<Collection<Object>> eventListenerProvider)
{
Checks.notNull(eventListenerProvider, "event listener provider");
this.getShardCache().forEach(jda ->
jda.removeEventListener(eventListenerProvider.apply(jda.getShardInfo().getShardId()))
);
}

/**
* Remove a listener provider. This will stop further created / restarted shards from getting a listener added by
* that provider.
*
* Default is a no-op for backwards compatibility, see implementations like
* {@link DefaultShardManager#removeEventListenerProvider(IntFunction)} for actual code
*
* @param eventListenerProvider
* The provider of listeners that shall be removed.
*
* @throws java.lang.IllegalArgumentException
* If the provided listener provider is {@code null}.
*/
default void removeEventListenerProvider(IntFunction<Object> eventListenerProvider)
{
}

/**
* Returns the amount of shards queued for (re)connecting.
*
Expand Down
Loading

0 comments on commit 3092875

Please sign in to comment.