Skip to content

Commit

Permalink
Add option to control user cache
Browse files Browse the repository at this point in the history
And make it disabled by default (breaking change!).
  • Loading branch information
Bastian committed Jul 16, 2021
1 parent 34d9d94 commit 5efaa53
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 10 deletions.
22 changes: 22 additions & 0 deletions javacord-api/src/main/java/org/javacord/api/DiscordApiBuilder.java
Expand Up @@ -439,6 +439,28 @@ public DiscordApiBuilder setAllIntentsWhere(Predicate<Intent> condition) {
return this;
}

/**
* Sets whether or not the user cache should be enabled.
*
* <p>By default, the user cache is disabled.
*
* @param enabled Whether or not the user cache should be enabled.
* @return The current instance in order to chain call methods.
*/
public DiscordApiBuilder setUserCacheEnabled(boolean enabled) {
delegate.setUserCacheEnabled(enabled);
return this;
}

/**
* Gets whether or not the user cache is enabled.
*
* @return Whether or not the user cache is enabled.
*/
public boolean isUserCachedEnabled() {
return delegate.isUserCacheEnabled();
}

/**
* Retrieves the recommended shards count from the Discord API and sets it in this builder.
* Sharding allows you to split your bot into several independent instances.
Expand Down
Expand Up @@ -178,6 +178,22 @@ public interface DiscordApiBuilderDelegate {
*/
void setAllIntentsWhere(Predicate<Intent> condition);

/**
* Sets whether or not the user cache should be enabled.
*
* <p>By default, the user cache is disabled.
*
* @param enabled Whether or not the user cache should be enabled.
*/
void setUserCacheEnabled(boolean enabled);

/**
* Gets whether or not the user cache is enabled.
*
* @return Whether or not the user cache is enabled.
*/
boolean isUserCacheEnabled();

/**
* Logs the bot in.
*
Expand Down
Expand Up @@ -129,6 +129,11 @@ public class DiscordApiBuilderDelegateImpl implements DiscordApiBuilderDelegate
private Set<Intent> intents = Arrays.stream(Intent.values())
.filter(intent -> !intent.isPrivileged()).collect(Collectors.toCollection(HashSet::new));

/**
* Whether the user cache should be enabled or not.
*/
private boolean userCacheEnabled = false;

/**
* The globally attachable listeners to register for every created DiscordApi instance.
*/
Expand Down Expand Up @@ -194,7 +199,7 @@ public CompletableFuture<DiscordApi> login() {
new DiscordApiImpl(accountType, token, currentShard.get(), totalShards.get(), intents,
waitForServersOnStartup, waitForUsersOnStartup, registerShutdownHook, globalRatelimiter,
gatewayIdentifyRatelimiter, proxySelector, proxy, proxyAuthenticator, trustAllCertificates,
future, null, preparedListeners, preparedUnspecifiedListeners);
future, null, preparedListeners, preparedUnspecifiedListeners, userCacheEnabled);
}
return future;
}
Expand Down Expand Up @@ -395,6 +400,16 @@ public void setAllIntentsWhere(Predicate<Intent> condition) {
}
}

@Override
public void setUserCacheEnabled(boolean enabled) {
userCacheEnabled = enabled;
}

@Override
public boolean isUserCacheEnabled() {
return userCacheEnabled;
}

@Override
public CompletableFuture<Void> setRecommendedTotalShards() {
CompletableFuture<Void> future = new CompletableFuture<>();
Expand Down
18 changes: 12 additions & 6 deletions javacord-core/src/main/java/org/javacord/core/DiscordApiImpl.java
Expand Up @@ -462,7 +462,7 @@ public DiscordApiImpl(
) {
this(accountType, token, currentShard, totalShards, intents, waitForServersOnStartup, waitForUsersOnStartup,
true, globalRatelimiter, gatewayIdentifyRatelimiter, proxySelector, proxy, proxyAuthenticator,
trustAllCertificates, ready, null, Collections.emptyMap(), Collections.emptyList());
trustAllCertificates, ready, null, Collections.emptyMap(), Collections.emptyList(), false);
}

/**
Expand Down Expand Up @@ -509,7 +509,7 @@ private DiscordApiImpl(
Dns dns) {
this(accountType, token, currentShard, totalShards, intents, waitForServersOnStartup, waitForUsersOnStartup,
true, globalRatelimiter, gatewayIdentifyRatelimiter, proxySelector, proxy, proxyAuthenticator,
trustAllCertificates, ready, dns, Collections.emptyMap(), Collections.emptyList());
trustAllCertificates, ready, dns, Collections.emptyMap(), Collections.emptyList(), false);
}

/**
Expand All @@ -532,13 +532,14 @@ private DiscordApiImpl(
* websocket.
* @param proxyAuthenticator The authenticator that should be used to authenticate against proxies that
* require it.
* @param trustAllCertificates Whether to trust all SSL certificates.
* @param trustAllCertificates Whether to trust all SSL certificates.
* @param ready The future which will be completed when the connection to Discord was
* successful.
* @param dns The DNS instance to use in the OkHttp client. This should only be used in
* testing.
* @param listenerSourceMap The functions to create listeners for pre-registration.
* @param unspecifiedListeners The listeners of unspecified types to pre-register.
* @param unspecifiedListeners The listeners of unspecified types to pre-register.
* @param userCacheEnabled Whether or not the user cache should be enabled.
*/
@SuppressWarnings("unchecked")
public DiscordApiImpl(
Expand All @@ -561,7 +562,9 @@ public DiscordApiImpl(
Map<Class<? extends GloballyAttachableListener>,
List<Function<DiscordApi,GloballyAttachableListener>>
> listenerSourceMap,
List<Function<DiscordApi, GloballyAttachableListener>> unspecifiedListeners) {
List<Function<DiscordApi, GloballyAttachableListener>> unspecifiedListeners,
boolean userCacheEnabled
) {
this.accountType = accountType;
this.token = token;
this.currentShard = currentShard;
Expand All @@ -575,7 +578,7 @@ public DiscordApiImpl(
this.proxyAuthenticator = proxyAuthenticator;
this.trustAllCertificates = trustAllCertificates;
this.intents = intents;
userCacheEnabled = intents.contains(Intent.GUILD_MEMBERS);
this.userCacheEnabled = userCacheEnabled;
this.reconnectDelayProvider = x ->
(int) Math.round(Math.pow(x, 1.5) - (1 / (1 / (0.1 * x) + 1)) * Math.pow(x, 1.5));

Expand Down Expand Up @@ -940,6 +943,9 @@ public void removeChannelFromCache(long channelId) {
* @param member The member to add.
*/
public void addMemberToCacheOrReplaceExisting(Member member) {
if (!isUserCacheEnabled()) {
return;
}
entityCache.getAndUpdate(cache -> {
Member oldMember = cache.getMemberCache()
.getMemberByIdAndServer(member.getId(), member.getServer().getId())
Expand Down
Expand Up @@ -420,10 +420,8 @@ && getMembers().size() < getMemberCount()
.orElse(null);

if (user == null) {
// In theory, every user in "presences" should also be in "members", but Discord is weird
// sometimes. This happens very rarely, but when it happens, we should ignore the presence.
// Ignore rouge presences.
// It might be a similar issue than https://github.com/discordapp/discord-api-docs/issues/855
logger.debug("Found rogue presence. Ignoring it. ({})", presenceJson);
continue;
}

Expand Down

0 comments on commit 5efaa53

Please sign in to comment.