diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index b6a8f55957..81cfdc4984 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -544,14 +544,27 @@ default ImageProxy getIcon() /** * The Features of the {@link net.dv8tion.jda.api.entities.Guild Guild}. - *

- * List of Features + * + *

Features can be updated using {@link GuildManager#setFeatures(Collection)}. * * @return Never-null, unmodifiable Set containing all of the Guild's features. + * + * @see List of Features */ @Nonnull Set getFeatures(); + /** + * Whether the invites for this guild are paused/disabled. + *
This is equivalent to {@code getFeatures().contains("INVITES_DISABLED")}. + * + * @return True, if invites are paused/disabled + */ + default boolean isInvitesDisabled() + { + return getFeatures().contains("INVITES_DISABLED"); + } + /** * The Discord hash-id of the splash image for this Guild. A Splash image is an image displayed when viewing a * Discord Guild Invite on the web or in client just before accepting or declining the invite. diff --git a/src/main/java/net/dv8tion/jda/api/managers/GuildManager.java b/src/main/java/net/dv8tion/jda/api/managers/GuildManager.java index 92f6850d07..3fc4dfe102 100644 --- a/src/main/java/net/dv8tion/jda/api/managers/GuildManager.java +++ b/src/main/java/net/dv8tion/jda/api/managers/GuildManager.java @@ -20,10 +20,13 @@ import net.dv8tion.jda.api.entities.Icon; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; +import net.dv8tion.jda.internal.utils.Checks; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.Collection; /** * Manager providing functionality to update one or more fields for a {@link net.dv8tion.jda.api.entities.Guild Guild}. @@ -73,6 +76,8 @@ public interface GuildManager extends Manager long COMMUNITY_UPDATES_CHANNEL = 1 << 13; /** Used to reset the premium progress bar enabled field */ long BOOST_PROGRESS_BAR_ENABLED = 1 << 14; + /** Used to add or remove modifiable features (such as {@code "INVITES_DISABLED"}) */ + long FEATURES = 1 << 15; /** * Resets the fields specified by the provided bit-flag pattern. @@ -94,6 +99,7 @@ public interface GuildManager extends Manager *

  • {@link #EXPLICIT_CONTENT_LEVEL}
  • *
  • {@link #VERIFICATION_LEVEL}
  • *
  • {@link #BOOST_PROGRESS_BAR_ENABLED}
  • + *
  • {@link #FEATURES}
  • * * * @param fields @@ -125,6 +131,7 @@ public interface GuildManager extends Manager *
  • {@link #EXPLICIT_CONTENT_LEVEL}
  • *
  • {@link #VERIFICATION_LEVEL}
  • *
  • {@link #BOOST_PROGRESS_BAR_ENABLED}
  • + *
  • {@link #FEATURES}
  • * * * @param fields @@ -372,4 +379,122 @@ public interface GuildManager extends Manager @Nonnull @CheckReturnValue GuildManager setBoostProgressBarEnabled(boolean boostProgressBarEnabled); + + /** + * Configures the new {@link Guild#getFeatures() features} of the {@link Guild}. + *
    The list of available features, including which ones can be configured, is available in the + * Official Discord API Documentation. + * + *

    Example + *

    {@code
    +     * List features = new ArrayList<>(guild.getFeatures());
    +     * features.add("INVITES_DISABLED");
    +     * guild.getManager().setFeatures(features).queue();
    +     * }
    + * + * @param features + * The new features to use + * + * @throws IllegalArgumentException + * If the provided list is null + * + * @return GuildManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + GuildManager setFeatures(@Nonnull Collection features); + + /** + * Adds a {@link Guild#getFeatures() Guild Feature} to the list of features. + *
    The list of available features, including which ones can be configured, is available in the + * Official Discord API Documentation. + * + * @param features + * The features to add + * + * @throws IllegalArgumentException + * If any of the provided features is null + * + * @return GuildManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + GuildManager addFeatures(@Nonnull Collection features); + + /** + * Adds a {@link Guild#getFeatures() Guild Feature} to the list of features. + *
    The list of available features, including which ones can be configured, is available in the + * Official Discord API Documentation. + * + * @param features + * The features to add + * + * @throws IllegalArgumentException + * If any of the provided features is null + * + * @return GuildManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + default GuildManager addFeatures(@Nonnull String... features) + { + Checks.noneNull(features, "Features"); + return addFeatures(Arrays.asList(features)); + } + + /** + * Removes a {@link Guild#getFeatures() Guild Feature} from the list of features. + *
    The list of available features, including which ones can be configured, is available in the + * Official Discord API Documentation. + * + * @param features + * The features to remove + * + * @throws IllegalArgumentException + * If any of the provided features is null + * + * @return GuildManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + GuildManager removeFeatures(@Nonnull Collection features); + + /** + * Removes a {@link Guild#getFeatures() Guild Feature} from the list of features. + *
    The list of available features, including which ones can be configured, is available in the + * Official Discord API Documentation. + * + * @param features + * The features to remove + * + * @throws IllegalArgumentException + * If any of the provided features is null + * + * @return GuildManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + default GuildManager removeFeatures(@Nonnull String... features) + { + Checks.noneNull(features, "Features"); + return removeFeatures(Arrays.asList(features)); + } + + /** + * Configures the {@code INVITES_DISABLED} feature flag of this guild. + *
    This is equivalent to adding or removing the feature {@code INVITES_DISABLED} via {@link #setFeatures(Collection)}. + * + * @param disabled + * True, to pause/disable all invites to the guild + * + * @return GuildManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + default GuildManager setInvitesDisabled(boolean disabled) + { + if (disabled) + return addFeatures("INVITES_DISABLED"); + return removeFeatures("INVITES_DISABLED"); + } } diff --git a/src/main/java/net/dv8tion/jda/internal/managers/GuildManagerImpl.java b/src/main/java/net/dv8tion/jda/internal/managers/GuildManagerImpl.java index 741186a252..8eb9c07b83 100644 --- a/src/main/java/net/dv8tion/jda/internal/managers/GuildManagerImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/managers/GuildManagerImpl.java @@ -16,7 +16,6 @@ package net.dv8tion.jda.internal.managers; -import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Icon; @@ -32,6 +31,11 @@ import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; public class GuildManagerImpl extends ManagerBase implements GuildManager { @@ -47,11 +51,11 @@ public class GuildManagerImpl extends ManagerBase implements Guild protected int explicitContentLevel; protected int verificationLevel; protected boolean boostProgressBarEnabled; + protected Set features; public GuildManagerImpl(Guild guild) { super(guild.getJDA(), Route.Guilds.MODIFY_GUILD.compile(guild.getId())); - JDA api = guild.getJDA(); this.guild = guild; if (isPermissionChecksEnabled()) checkPermissions(); @@ -91,6 +95,8 @@ public GuildManagerImpl reset(long fields) this.description = null; if ((fields & BANNER) == BANNER) this.banner = null; + if ((fields & FEATURES) == FEATURES) + this.features = null; return this; } @@ -116,6 +122,7 @@ public GuildManagerImpl reset() this.banner = null; this.afkChannel = null; this.systemChannel = null; + this.features = null; return this; } @@ -284,6 +291,44 @@ public GuildManager setBoostProgressBarEnabled(boolean enabled) return this; } + @Nonnull + @Override + public GuildManager setFeatures(@Nonnull Collection features) + { + Checks.noneNull(features, "Features"); + this.features = features.stream() + .map(String::toUpperCase) + .collect(Collectors.toSet()); + set |= FEATURES; + return this; + } + + @Nonnull + @Override + public GuildManager addFeatures(@Nonnull Collection features) + { + return updateFeatures(features, this.features::add); + } + + @Nonnull + @Override + public GuildManager removeFeatures(@Nonnull Collection features) + { + return updateFeatures(features, this.features::remove); + } + + private GuildManager updateFeatures(Collection changed, Consumer op) + { + Checks.noneNull(changed, "Features"); + if (this.features == null) + this.features = new HashSet<>(getGuild().getFeatures()); + changed.stream() + .map(String::toUpperCase) + .forEach(op); + set |= FEATURES; + return this; + } + @Override protected RequestBody finalizeData() { @@ -318,6 +363,8 @@ protected RequestBody finalizeData() body.put("description", description); if (shouldUpdate(BOOST_PROGRESS_BAR_ENABLED)) body.put("premium_progress_bar_enabled", boostProgressBarEnabled); + if (shouldUpdate(FEATURES)) + body.put("features", features); reset(); //now that we've built our JSON object, reset the manager back to the non-modified state return getRequestBody(body);