Skip to content

Commit

Permalink
Merge pull request #1187 from DV8FromTheWorld/release/4.1.1
Browse files Browse the repository at this point in the history
Release 4.1.1
  • Loading branch information
MinnDevelopment authored Jan 24, 2020
2 parents 6d5db0f + 8d8ba81 commit d472d98
Show file tree
Hide file tree
Showing 87 changed files with 2,322 additions and 1,167 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,27 @@ Through [RestAction](https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/api/
and it is up to the user to decide which pattern to utilize.
It can be combined with reactive libraries such as [reactor-core](https://github.com/reactor/reactor-core) due to being lazy.

The RestAction interface also supports a number of operators to avoid callback hell:

- [`map`](https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/api/requests/RestAction.html#map%28java.util.function.Function%29)
Convert the result of the `RestAction` to a different value
- [`flatMap`](https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/api/requests/RestAction.html#flatMap%28java.util.function.Function%29)
Chain another `RestAction` on the result
- [`delay`](https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/api/requests/RestAction.html#delay%28java.time.Duration%29)
Delay the element of the previous step

**Example**:

```java
public RestAction<Void> selfDestruct(MessageChannel channel, String content) {
return channel.sendMessage("The following message will destroy itself in 1 minute!")
.delay(10, SECONDS, scheduler) // edit 10 seconds later
.flatMap((it) -> it.editMessage(content))
.delay(1, MINUTES, scheduler) // delete 1 minute later
.flatMap(Message::delete);
}
```

### More Examples

We provide a small set of Examples in the [Example Directory](https://github.com/DV8FromTheWorld/JDA/tree/master/src/examples/java).
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ plugins {
id("com.github.johnrengelman.shadow") version "5.1.0"
}

val versionObj = Version(major = "4", minor = "1", revision = "0")
val versionObj = Version(major = "4", minor = "1", revision = "1")

project.group = "net.dv8tion"
project.version = "$versionObj"
Expand Down
22 changes: 11 additions & 11 deletions src/examples/java/MessageListenerExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import javax.security.auth.login.LoginException;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

public class MessageListenerExample extends ListenerAdapter
{
Expand Down Expand Up @@ -142,20 +143,19 @@ else if (event.isFromType(ChannelType.PRIVATE)) //If this message was sent to a
}
else if (msg.equals("!roll"))
{
//In this case, we have an example showing how to use the Success consumer for a RestAction. The Success consumer
//In this case, we have an example showing how to use the flatMap operator for a RestAction. The operator
// will provide you with the object that results after you execute your RestAction. As a note, not all RestActions
// have object returns and will instead have Void returns. You can still use the success consumer to determine when
// the action has been completed!
// have object returns and will instead have Void returns. You can still use the flatMap operator to run chain another RestAction!

Random rand = new Random();
Random rand = ThreadLocalRandom.current();
int roll = rand.nextInt(6) + 1; //This results in 1 - 6 (instead of 0 - 5)
channel.sendMessage("Your roll: " + roll).queue(sentMessage -> //This is called a lambda statement. If you don't know
{ // what they are or how they work, try google!
if (roll < 3)
{
channel.sendMessage("The roll for messageId: " + sentMessage.getId() + " wasn't very good... Must be bad luck!\n").queue();
}
});
channel.sendMessage("Your roll: " + roll)
.flatMap(
(v) -> roll < 3, // This is called a lambda expression. If you don't know what they are or how they work, try google!
// Send another message if the roll was bad (less than 3)
sentMessage -> channel.sendMessage("The roll for messageId: " + sentMessage.getId() + " wasn't very good... Must be bad luck!\n")
)
.queue();
}
else if (msg.startsWith("!kick")) //Note, I used "startsWith, not equals.
{
Expand Down
14 changes: 12 additions & 2 deletions src/main/java/net/dv8tion/jda/api/JDA.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import net.dv8tion.jda.api.utils.MiscUtil;
import net.dv8tion.jda.api.utils.cache.CacheView;
import net.dv8tion.jda.api.utils.cache.SnowflakeCacheView;
import net.dv8tion.jda.internal.requests.EmptyRestAction;
import net.dv8tion.jda.internal.requests.CompletedRestAction;
import net.dv8tion.jda.internal.requests.RestActionImpl;
import net.dv8tion.jda.internal.requests.Route;
import net.dv8tion.jda.internal.utils.Checks;
Expand Down Expand Up @@ -813,6 +813,16 @@ default List<Guild> getGuildsByName(@Nonnull String name, boolean ignoreCase)
@Nonnull
Set<String> getUnavailableGuilds();

/**
* Whether the guild is unavailable. If this returns true, the guild id should be in {@link #getUnavailableGuilds()}.
*
* @param guildId
* The guild id
*
* @return True, if this guild is unavailable
*/
boolean isUnavailable(long guildId);

/**
* Unified {@link net.dv8tion.jda.api.utils.cache.SnowflakeCacheView SnowflakeCacheView} of
* all cached {@link net.dv8tion.jda.api.entities.Role Roles} visible to this JDA session.
Expand Down Expand Up @@ -1828,6 +1838,6 @@ default AuditableRestAction<Integer> installAuxiliaryPort()
}
}
else throw new IllegalStateException("No port available");
return new EmptyRestAction<>(this, port);
return new CompletedRestAction<>(this, port);
}
}
29 changes: 27 additions & 2 deletions src/main/java/net/dv8tion/jda/api/JDABuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public class JDABuilder
protected boolean idle = false;
protected int maxReconnectDelay = 900;
protected int largeThreshold = 250;
protected int maxBufferSize = 2048;
protected EnumSet<ConfigFlag> flags = ConfigFlag.getDefault();
protected ChunkingFilter chunkingFilter = ChunkingFilter.ALL;

Expand Down Expand Up @@ -155,7 +156,7 @@ public JDABuilder setRawEventsEnabled(boolean enable)

/**
* Whether the rate-limit should be relative to the current time plus latency.
* <br>By default we use the {@code X-RateLimit-Rest-After} header to determine when
* <br>By default we use the {@code X-RateLimit-Reset-After} header to determine when
* a rate-limit is no longer imminent. This has the disadvantage that it might wait longer than needed due
* to the latency which is ignored by the reset-after relative delay.
*
Expand Down Expand Up @@ -920,6 +921,30 @@ public JDABuilder setLargeThreshold(int threshold)
return this;
}

/**
* The maximum size, in bytes, of the buffer used for decompressing discord payloads.
* <br>If the maximum buffer size is exceeded a new buffer will be allocated instead.
* <br>Setting this to {@link Integer#MAX_VALUE} would imply the buffer will never be resized unless memory starvation is imminent.
* <br>Setting this to {@code 0} would imply the buffer would need to be allocated again for every payload (not recommended).
*
* <p>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 JDABuilder instance. Useful for chaining.
*/
@Nonnull
public JDABuilder setMaxBufferSize(int bufferSize)
{
Checks.notNegative(bufferSize, "The buffer size");
this.maxBufferSize = bufferSize;
return this;
}

/**
* Builds a new {@link net.dv8tion.jda.api.JDA} instance and uses the provided token to start the login process.
* <br>The login process runs in a different thread, so while this will return immediately, {@link net.dv8tion.jda.api.JDA} has not
Expand Down Expand Up @@ -964,7 +989,7 @@ public JDA build() throws LoginException
threadingConfig.setGatewayPool(mainWsPool, shutdownMainWsPool);
threadingConfig.setRateLimitPool(rateLimitPool, shutdownRateLimitPool);
SessionConfig sessionConfig = new SessionConfig(controller, httpClient, wsFactory, voiceDispatchInterceptor, flags, maxReconnectDelay, largeThreshold);
MetaConfig metaConfig = new MetaConfig(contextMap, cacheFlags, flags);
MetaConfig metaConfig = new MetaConfig(maxBufferSize, contextMap, cacheFlags, flags);

JDAImpl jda = new JDAImpl(authConfig, sessionConfig, threadingConfig, metaConfig);
jda.setChunkingFilter(chunkingFilter);
Expand Down
31 changes: 19 additions & 12 deletions src/main/java/net/dv8tion/jda/api/entities/Guild.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import net.dv8tion.jda.api.utils.cache.MemberCacheView;
import net.dv8tion.jda.api.utils.cache.SnowflakeCacheView;
import net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView;
import net.dv8tion.jda.internal.requests.EmptyRestAction;
import net.dv8tion.jda.internal.requests.DeferredRestAction;
import net.dv8tion.jda.internal.requests.Route;
import net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl;
import net.dv8tion.jda.internal.utils.Checks;
Expand Down Expand Up @@ -1628,13 +1628,18 @@ default RestAction<ListedEmote> retrieveEmote(@Nonnull Emote emote)
Checks.notNull(emote, "Emote");
if (emote.getGuild() != null)
Checks.check(emote.getGuild().equals(this), "Emote must be from the same Guild!");
if (emote instanceof ListedEmote && !emote.isFake())
{
ListedEmote listedEmote = (ListedEmote) emote;
if (listedEmote.hasUser() || !getSelfMember().hasPermission(Permission.MANAGE_EMOTES))
return new EmptyRestAction<>(getJDA(), listedEmote);
}
return retrieveEmoteById(emote.getId());

JDA jda = getJDA();
return new DeferredRestAction<>(jda, ListedEmote.class,
() -> {
if (emote instanceof ListedEmote && !emote.isFake())
{
ListedEmote listedEmote = (ListedEmote) emote;
if (listedEmote.hasUser() || !getSelfMember().hasPermission(Permission.MANAGE_EMOTES))
return listedEmote;
}
return null;
}, () -> retrieveEmoteById(emote.getId()));
}

/**
Expand Down Expand Up @@ -2029,17 +2034,19 @@ default RestAction<Ban> retrieveBan(@Nonnull User bannedUser)
boolean checkVerification();

/**
* Returns whether or not this Guild is available. A Guild can be unavailable, if the Discord server has problems.
* <br>If a Guild is unavailable, no actions on it can be performed (Messages, Manager,...)
* Whether or not this Guild is available. A Guild can be unavailable, if the Discord server has problems.
* <br>If a Guild is unavailable, it will be removed from the guild cache. You cannot receive events for unavailable guilds.
*
* @return If the Guild is available
*
* @deprecated
* This will be removed in a future version, unavailable guilds are now removed from cache
* @deprecated This will be removed in a future version,
* unavailable guilds are now removed from cache.
* Replace with {@link JDA#isUnavailable(long)}
*/
@ForRemoval
@Deprecated
@DeprecatedSince("4.1.0")
@ReplaceWith("getJDA().isUnavailable(guild.getIdLong())")
boolean isAvailable();

/**
Expand Down
13 changes: 12 additions & 1 deletion src/main/java/net/dv8tion/jda/api/entities/GuildChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.dv8tion.jda.api.entities;

import gnu.trove.map.TLongObjectMap;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
Expand All @@ -24,6 +25,8 @@
import net.dv8tion.jda.api.requests.restaction.ChannelAction;
import net.dv8tion.jda.api.requests.restaction.InviteAction;
import net.dv8tion.jda.api.requests.restaction.PermissionOverrideAction;
import net.dv8tion.jda.api.utils.data.DataObject;
import net.dv8tion.jda.internal.entities.GuildImpl;

import javax.annotation.CheckReturnValue;
import javax.annotation.Nonnull;
Expand Down Expand Up @@ -363,7 +366,15 @@ default PermissionOverrideAction upsertPermissionOverride(@Nonnull IPermissionHo
if (!getGuild().getSelfMember().hasPermission(this, Permission.MANAGE_PERMISSIONS))
throw new InsufficientPermissionException(this, Permission.MANAGE_PERMISSIONS);
PermissionOverride override = getPermissionOverride(permissionHolder);
return override != null ? override.getManager() : putPermissionOverride(permissionHolder);
if (override != null)
return override.getManager();
PermissionOverrideAction action = putPermissionOverride(permissionHolder);
// Check if we have some information cached already
TLongObjectMap<DataObject> cache = ((GuildImpl) getGuild()).getOverrideMap(permissionHolder.getIdLong());
DataObject json = cache == null ? null : cache.get(getIdLong());
if (json != null)
action = action.setPermissions(json.getLong("allow"), json.getLong("deny"));
return action;
}

/**
Expand Down
Loading

0 comments on commit d472d98

Please sign in to comment.