diff --git a/javacord-api/src/main/java/org/javacord/api/entity/VanityUrlCode.java b/javacord-api/src/main/java/org/javacord/api/entity/VanityUrlCode.java new file mode 100644 index 0000000000..0ba342a409 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/entity/VanityUrlCode.java @@ -0,0 +1,21 @@ +package org.javacord.api.entity; + +import java.net.URL; + +public interface VanityUrlCode { + + /** + * Gets the vanity code. + * + * @return The vanity code. + */ + String getCode(); + + /** + * Gets the vanity url. + * + * @return The URL of the vanity code. + */ + URL getUrl(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/entity/server/BoostLevel.java b/javacord-api/src/main/java/org/javacord/api/entity/server/BoostLevel.java new file mode 100644 index 0000000000..99a5e37688 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/entity/server/BoostLevel.java @@ -0,0 +1,69 @@ +package org.javacord.api.entity.server; + +/** + * An enum with all boost levels (sometimes also referred to as premium tier levels). + */ +public enum BoostLevel { + + /** + * Server has no boost level. + */ + NONE(0), + /** + * Server Boost level 1. + */ + TIER_1(1), + /** + * Server Boost level 2. + */ + TIER_2(2), + + /** + * Server Boost level 3. + */ + TIER_3(2), + + /** + * An unknown boost level, most likely due to new added boost levels. + */ + UNKNOWN(-1); + + + /** + * The id of the boost level. + */ + private final int id; + + /** + * Creates a new boost level. + * + * @param id The id of the boost level. + */ + BoostLevel(int id) { + this.id = id; + } + + /** + * Gets the id of the boost level. + * + * @return The id of the boost level. + */ + public int getId() { + return id; + } + + /** + * Gets the boost level by its id. + * + * @param id The id of the boost level. + * @return The boost level with the given id. + */ + public static BoostLevel fromId(int id) { + for (BoostLevel boostLevel : values()) { + if (boostLevel.getId() == id) { + return boostLevel; + } + } + return UNKNOWN; + } +} diff --git a/javacord-api/src/main/java/org/javacord/api/entity/server/Server.java b/javacord-api/src/main/java/org/javacord/api/entity/server/Server.java index 177d204d32..83166647ef 100644 --- a/javacord-api/src/main/java/org/javacord/api/entity/server/Server.java +++ b/javacord-api/src/main/java/org/javacord/api/entity/server/Server.java @@ -5,6 +5,7 @@ import org.javacord.api.entity.Nameable; import org.javacord.api.entity.Region; import org.javacord.api.entity.UpdatableFromCache; +import org.javacord.api.entity.VanityUrlCode; import org.javacord.api.entity.auditlog.AuditLog; import org.javacord.api.entity.auditlog.AuditLogActionType; import org.javacord.api.entity.auditlog.AuditLogEntry; @@ -40,6 +41,7 @@ import java.util.Comparator; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; @@ -49,6 +51,99 @@ */ public interface Server extends DiscordEntity, Nameable, UpdatableFromCache, ServerAttachableListenerManager { + /** + * Checks if the server has boost messages enabled. + * + * @return Whether the the server has boost messages enabled or not. + */ + boolean hasBoostMessagesEnabled(); + + /** + * Checks if the server has join messages enabled. + * + * @return Whether the the server has join messages enabled or not. + */ + boolean hasJoinMessagesEnabled(); + + /** + * Gets the features of the server. + * + * @return The server's available features. + */ + Collection getFeatures(); + + /** + * Gets the boost level of the server. + * + * @return The boost level. + */ + BoostLevel getBoostLevel(); + + /** + * Gets the boost count of the server. + * + * @return The boost count. + */ + int getBoostCount(); + + /** + * Gets the rules channel. + * + *

Rule channels are only available for public servers. + * You can check if a server is public using the {@link #getFeatures()} methods. + * + * @return The rules channel. + */ + Optional getRulesChannel(); + + /** + * Gets the description of the server. + * + * @return The description. + */ + Optional getDescription(); + + /** + * Gets the moderators-only channel (sometimes also called "public updates channel"). + * + *

This is the channel where Discord will send announcements and updates relevant + * to Public server admins and moderators, like new moderation features and the + * server's eligibility in Discovery. + * + *

Moderator-only channels are only available for public servers. + * You can check if a server is public using the {@link #getFeatures()} method. + * + * @return The moderators-only channel. + */ + Optional getModeratorsOnlyChannel(); + + /** + * Gets the vanity url code of the server. + * + * @return The vanity url code. + */ + Optional getVanityUrlCode(); + + /** + * Gets the discovery splash of the server. + * + * @return The discovery splash. + */ + Optional getDiscoverySplash(); + + /** + * Gets the server's preferred locale. + * + *

Discord will prioritize this server in Discovery to users who speak + * the selected language. Updates sent from Discord in the Moderators-only + * channel will also be in this language. + * + *

Setting a preferred locale is only available for public servers. + * You can check if a server is public using the {@link #getFeatures()} methods. + * @return The sever's preferred locale. + */ + Locale getPreferredLocale(); + /** * Gets the region of the server. * @@ -355,8 +450,8 @@ default Optional getMemberById(String id) { */ default Optional getMemberByDiscriminatedName(String discriminatedName) { String[] nameAndDiscriminator = discriminatedName.split("#", 2); - return (nameAndDiscriminator.length > 1) - ? getMemberByNameAndDiscriminator(nameAndDiscriminator[0], nameAndDiscriminator[1]) + return (nameAndDiscriminator.length > 1) + ? getMemberByNameAndDiscriminator(nameAndDiscriminator[0], nameAndDiscriminator[1]) : Optional.empty(); } @@ -369,8 +464,8 @@ default Optional getMemberByDiscriminatedName(String discriminatedName) { */ default Optional getMemberByDiscriminatedNameIgnoreCase(String discriminatedName) { String[] nameAndDiscriminator = discriminatedName.split("#", 2); - return (nameAndDiscriminator.length > 1) - ? getMemberByNameAndDiscriminatorIgnoreCase(nameAndDiscriminator[0], nameAndDiscriminator[1]) + return (nameAndDiscriminator.length > 1) + ? getMemberByNameAndDiscriminatorIgnoreCase(nameAndDiscriminator[0], nameAndDiscriminator[1]) : Optional.empty(); } @@ -930,7 +1025,7 @@ default CompletableFuture updateOwner(User owner) { } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * This method assumes the file type is "png"! * *

If you want to update several settings at once, it's recommended to use the @@ -944,7 +1039,7 @@ default CompletableFuture updateSplash(BufferedImage splash) { } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * *

If you want to update several settings at once, it's recommended to use the * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! @@ -958,7 +1053,7 @@ default CompletableFuture updateSplash(BufferedImage splash, String fileTy } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * *

If you want to update several settings at once, it's recommended to use the * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! @@ -971,7 +1066,7 @@ default CompletableFuture updateSplash(File splash) { } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * *

If you want to update several settings at once, it's recommended to use the * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! @@ -984,7 +1079,7 @@ default CompletableFuture updateSplash(Icon splash) { } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * *

If you want to update several settings at once, it's recommended to use the * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! @@ -997,7 +1092,7 @@ default CompletableFuture updateSplash(URL splash) { } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * This method assumes the file type is "png"! * *

If you want to update several settings at once, it's recommended to use the @@ -1011,7 +1106,7 @@ default CompletableFuture updateSplash(byte[] splash) { } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * *

If you want to update several settings at once, it's recommended to use the * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! @@ -1025,7 +1120,7 @@ default CompletableFuture updateSplash(byte[] splash, String fileType) { } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * This method assumes the file type is "png"! * *

If you want to update several settings at once, it's recommended to use the @@ -1039,7 +1134,7 @@ default CompletableFuture updateSplash(InputStream splash) { } /** - * Updates the splash of the server. + * Updates the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * *

If you want to update several settings at once, it's recommended to use the * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! @@ -1053,7 +1148,7 @@ default CompletableFuture updateSplash(InputStream splash, String fileType } /** - * Removes the splash of the server. + * Removes the splash of the server. Requires {@link ServerFeature#INVITE_SPLASH}. * *

If you want to update several settings at once, it's recommended to use the * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! @@ -1064,6 +1159,205 @@ default CompletableFuture removeSplash() { return createUpdater().removeSplash().update(); } + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * This method assumes the file type is "png"! + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(BufferedImage banner) { + return createUpdater().setBanner(banner).update(); + } + + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(BufferedImage banner, String fileType) { + return createUpdater().setBanner(banner, fileType).update(); + } + + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. Requires {@link ServerFeature#BANNER}. + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(File banner) { + return createUpdater().setBanner(banner).update(); + } + + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(Icon banner) { + return createUpdater().setBanner(banner).update(); + } + + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(URL banner) { + return createUpdater().setBanner(banner).update(); + } + + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * This method assumes the file type is "png"! + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(byte[] banner) { + return createUpdater().setBanner(banner).update(); + } + + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(byte[] banner, String fileType) { + return createUpdater().setBanner(banner, fileType).update(); + } + + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * This method assumes the file type is "png"! + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(InputStream banner) { + return createUpdater().setBanner(banner).update(); + } + + /** + * Updates the banner of the server. Requires {@link ServerFeature#BANNER}. + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + * @return A future to check if the update was successful. + */ + default CompletableFuture updateBanner(InputStream banner, String fileType) { + return createUpdater().setBanner(banner, fileType).update(); + } + + /** + * Removes the banner of the server. Requires {@link ServerFeature#BANNER}. + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @return A future to check if the removal was successful. + */ + default CompletableFuture removeBanner() { + return createUpdater().removeBanner().update(); + } + + /** + * Updates the rules channel of the server. Server has to be "PUBLIC". + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param rulesChannel The new rules channel of the server. + * @return A future to check if the update was successful. + */ + default CompletableFuture setRulesChannel(ServerTextChannel rulesChannel) { + return createUpdater().setRulesChannel(rulesChannel).update(); + } + + /** + * Removes the rules channel of the server. Server has to be "PUBLIC". + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @return A future to check if the update was successful. + */ + default CompletableFuture removeRulesChannel() { + return createUpdater().removeRulesChannel().update(); + } + + + /** + * Updates the moderators-only channel of the server. Server has to be "PUBLIC". + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param moderatorsOnlyChannel The new moderators-only of the server. + * @return A future to check if the update was successful. + */ + default CompletableFuture setModeratorsOnlyChannel(ServerTextChannel moderatorsOnlyChannel) { + return createUpdater().setModeratorsOnlyChannel(moderatorsOnlyChannel).update(); + } + + /** + * Removes the moderators-only channel of the server. Server has to be "PUBLIC". + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @return A future to check if the update was successful. + */ + default CompletableFuture removeModeratorsOnlyChannel() { + return createUpdater().removeModeratorsOnlyChannel().update(); + } + + /** + * Updates the locale of the server. Server has to be "PUBLIC". + * + *

If you want to update several settings at once, it's recommended to use the + * {@link ServerUpdater} from {@link #createUpdater()} which provides a better performance! + * + * @param locale The new locale of the server. + * @return A future to check if the update was successful. + */ + default CompletableFuture updatePreferredLocale(Locale locale) { + return createUpdater().setPreferredLocale(locale).update(); + } + /** * Updates the system channel of the server. * diff --git a/javacord-api/src/main/java/org/javacord/api/entity/server/ServerFeature.java b/javacord-api/src/main/java/org/javacord/api/entity/server/ServerFeature.java new file mode 100644 index 0000000000..7524a1207d --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/entity/server/ServerFeature.java @@ -0,0 +1,64 @@ +package org.javacord.api.entity.server; + +/** + * An enum with all server features. + */ +public enum ServerFeature { + + /** + * Server has access to set an invite splash background. + */ + INVITE_SPLASH, + /** + * Server has access to set 384kbps bitrate in voice (previously VIP voice servers). + */ + VIP_REGIONS, + /** + * Server has access to set a vanity URL. + */ + VANITY_URL, + /** + * Server is verified. + */ + VERIFIED, + /** + * Server is partnered. + */ + PARTNERED, + /** + * Server is public. + */ + PUBLIC, + /** + * Server has access to use commerce features (i.e. create store channels). + */ + COMMERCE, + /** + * Server has access to create news channels. + */ + NEWS, + /** + * Server is able to be discovered in the directory. + */ + DISCOVERABLE, + /** + * Server is able to be featured in the directory. + */ + FEATURABLE, + /** + * Server has access to set an animated Server icon. + */ + ANIMATED_ICON, + /** + * Server has access to set a Server banner image. + */ + BANNER, + /** + * Server cannot be public. + */ + PUBLIC_DISABLED, + /** + * Server has enabled the welcome screen. + */ + WELCOME_SCREEN_ENABLED +} diff --git a/javacord-api/src/main/java/org/javacord/api/entity/server/ServerUpdater.java b/javacord-api/src/main/java/org/javacord/api/entity/server/ServerUpdater.java index 2e8c705347..55f3c88a01 100644 --- a/javacord-api/src/main/java/org/javacord/api/entity/server/ServerUpdater.java +++ b/javacord-api/src/main/java/org/javacord/api/entity/server/ServerUpdater.java @@ -15,6 +15,7 @@ import java.net.URL; import java.util.Collection; import java.util.List; +import java.util.Locale; import java.util.concurrent.CompletableFuture; /** @@ -275,7 +276,7 @@ public ServerUpdater setSplash(BufferedImage splash) { } /** - * Queues the splash to be updated. + * Queues the splash to be updated. Requires {@link ServerFeature#INVITE_SPLASH}. * * @param splash The new splash of the server. * @param fileType The type of the splash, e.g. "png" or "jpg". @@ -287,7 +288,7 @@ public ServerUpdater setSplash(BufferedImage splash, String fileType) { } /** - * Queues the splash to be updated. + * Queues the splash to be updated. Requires {@link ServerFeature#INVITE_SPLASH}. * * @param splash The new splash of the server. * @return The current instance in order to chain call methods. @@ -298,7 +299,7 @@ public ServerUpdater setSplash(File splash) { } /** - * Queues the splash to be updated. + * Queues the splash to be updated. Requires {@link ServerFeature#INVITE_SPLASH}. * * @param splash The new splash of the server. * @return The current instance in order to chain call methods. @@ -309,7 +310,7 @@ public ServerUpdater setSplash(Icon splash) { } /** - * Queues the splash to be updated. + * Queues the splash to be updated. Requires {@link ServerFeature#INVITE_SPLASH}. * * @param splash The new splash of the server. * @return The current instance in order to chain call methods. @@ -320,7 +321,7 @@ public ServerUpdater setSplash(URL splash) { } /** - * Queues the splash to be updated. + * Queues the splash to be updated. Requires {@link ServerFeature#INVITE_SPLASH}. * This method assumes the file type is "png"! * * @param splash The new splash of the server. @@ -332,7 +333,7 @@ public ServerUpdater setSplash(byte[] splash) { } /** - * Queues the splash to be updated. + * Queues the splash to be updated. Requires {@link ServerFeature#INVITE_SPLASH}. * * @param splash The new splash of the server. * @param fileType The type of the splash, e.g. "png" or "jpg". @@ -344,7 +345,7 @@ public ServerUpdater setSplash(byte[] splash, String fileType) { } /** - * Queues the splash to be updated. + * Queues the splash to be updated. Requires {@link ServerFeature#INVITE_SPLASH}. * This method assumes the file type is "png"! * * @param splash The new splash of the server. @@ -356,7 +357,7 @@ public ServerUpdater setSplash(InputStream splash) { } /** - * Queues the splash to be updated. + * Queues the splash to be updated. Requires {@link ServerFeature#INVITE_SPLASH}. * * @param splash The new splash of the server. * @param fileType The type of the splash, e.g. "png" or "jpg". @@ -368,7 +369,7 @@ public ServerUpdater setSplash(InputStream splash, String fileType) { } /** - * Queues the splash to be removed. + * Queues the splash to be removed. Requires {@link ServerFeature#INVITE_SPLASH}. * * @return The current instance in order to chain call methods. */ @@ -377,6 +378,174 @@ public ServerUpdater removeSplash() { return this; } + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * This method assumes the file type is "png"! + * + * @param banner The new banner of the server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(BufferedImage banner) { + delegate.setBanner(banner); + return this; + } + + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(BufferedImage banner, String fileType) { + delegate.setBanner(banner, fileType); + return this; + } + + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * + * @param banner The new banner of the server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(File banner) { + delegate.setBanner(banner); + return this; + } + + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * + * @param banner The new banner of the server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(Icon banner) { + delegate.setBanner(banner); + return this; + } + + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * + * @param banner The new banner of the server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(URL banner) { + delegate.setBanner(banner); + return this; + } + + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * This method assumes the file type is "png"! + * + * @param banner The new banner of the server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(byte[] banner) { + delegate.setBanner(banner); + return this; + } + + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(byte[] banner, String fileType) { + delegate.setBanner(banner, fileType); + return this; + } + + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * This method assumes the file type is "png"! + * + * @param banner The new banner of the server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(InputStream banner) { + delegate.setBanner(banner); + return this; + } + + /** + * Queues the banner to be updated. Requires {@link ServerFeature#BANNER}. + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setBanner(InputStream banner, String fileType) { + delegate.setBanner(banner, fileType); + return this; + } + + /** + * Queues the banner to be removed. Requires {@link ServerFeature#BANNER}. + * + * @return The current instance in order to chain call methods. + */ + public ServerUpdater removeBanner() { + delegate.removeBanner(); + return this; + } + + /** + * Queues the rules channel to be updated. Server has to be "PUBLIC". + * + * @param rulesChannel The new rules channel of the server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setRulesChannel(ServerTextChannel rulesChannel) { + delegate.setRulesChannel(rulesChannel); + return this; + } + + /** + * Queues the rules channel to be removed. Server has to be "PUBLIC". + * + * @return The current instance in order to chain call methods. + */ + public ServerUpdater removeRulesChannel() { + delegate.removeRulesChannel(); + return this; + } + + /** + * Queues the moderators-only channel to be updated. Server has to be "PUBLIC". + * + * @param moderatorsOnlyChannel The new moderators-only channel of the server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setModeratorsOnlyChannel(ServerTextChannel moderatorsOnlyChannel) { + delegate.setModeratorsOnlyChannel(moderatorsOnlyChannel); + return this; + } + + /** + * Queues the moderators-only channel to be removed. Server has to be "PUBLIC". + * + * @return The current instance in order to chain call methods. + */ + public ServerUpdater removeModeratorsOnlyChannel() { + delegate.removeModeratorsOnlyChannel(); + return this; + } + + /** + * Queues the preferred locale of a public guild to be updated. + * + * @param locale The preferred locale of the public server. + * @return The current instance in order to chain call methods. + */ + public ServerUpdater setPreferredLocale(Locale locale) { + delegate.setPreferredLocale(locale); + return this; + } + /** * Queues the system channel to be updated. * diff --git a/javacord-api/src/main/java/org/javacord/api/entity/server/internal/ServerUpdaterDelegate.java b/javacord-api/src/main/java/org/javacord/api/entity/server/internal/ServerUpdaterDelegate.java index ec44c42753..b8308fe267 100644 --- a/javacord-api/src/main/java/org/javacord/api/entity/server/internal/ServerUpdaterDelegate.java +++ b/javacord-api/src/main/java/org/javacord/api/entity/server/internal/ServerUpdaterDelegate.java @@ -17,6 +17,7 @@ import java.net.URL; import java.util.Collection; import java.util.List; +import java.util.Locale; import java.util.concurrent.CompletableFuture; /** @@ -242,6 +243,111 @@ public interface ServerUpdaterDelegate { */ void removeSplash(); + /** + * Queues the banner to be updated. + * This method assumes the file type is "png"! + * + * @param banner The new banner of the server. + */ + void setBanner(BufferedImage banner); + + /** + * Queues the banner to be updated. + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + */ + void setBanner(BufferedImage banner, String fileType); + + /** + * Queues the banner to be updated. + * + * @param banner The new banner of the server. + */ + void setBanner(File banner); + + /** + * Queues the banner to be updated. + * + * @param banner The new banner of the server. + */ + void setBanner(Icon banner); + + /** + * Queues the banner to be updated. + * + * @param banner The new banner of the server. + */ + void setBanner(URL banner); + + /** + * Queues the banner to be updated. + * This method assumes the file type is "png"! + * + * @param banner The new banner of the server. + */ + void setBanner(byte[] banner); + + /** + * Queues the banner to be updated. + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + */ + void setBanner(byte[] banner, String fileType); + + /** + * Queues the banner to be updated. + * This method assumes the file type is "png"! + * + * @param banner The new banner of the server. + */ + void setBanner(InputStream banner); + + /** + * Queues the banner to be updated. + * + * @param banner The new banner of the server. + * @param fileType The type of the banner, e.g. "png" or "jpg". + */ + void setBanner(InputStream banner, String fileType); + + /** + * Queues the banner to be removed. + */ + void removeBanner(); + + /** + * Queues the rules channel to be updated. + * + * @param rulesChannel The new rules channel of the server. + */ + void setRulesChannel(ServerTextChannel rulesChannel); + + /** + * Queues the rules channel to be removed. + */ + void removeRulesChannel(); + + /** + * Queues the moderators-only channel to be updated. + * + * @param moderatorsOnlyChannel The new moderators-only channel of the server. + */ + void setModeratorsOnlyChannel(ServerTextChannel moderatorsOnlyChannel); + + /** + * Queues the moderators-only channel to be removed. + */ + void removeModeratorsOnlyChannel(); + + /** + * Queues the locale of a "PUBLIC" server to be updated. + * + * @param locale The new locale of the public server + */ + void setPreferredLocale(Locale locale); + /** * Queues the system channel to be updated. * diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeBoostCountEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeBoostCountEvent.java new file mode 100644 index 0000000000..13db7364be --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeBoostCountEvent.java @@ -0,0 +1,22 @@ +package org.javacord.api.event.server; + +/** + * A server change boost count event. + */ +public interface ServerChangeBoostCountEvent extends ServerEvent { + + /** + * Gets the old boost count of the server. + * + * @return The old boost count of the server. + */ + int getOldBoostCount(); + + /** + * Gets the new boost count of the server. + * + * @return The new boost count of the server. + */ + int getNewBoostCount(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeBoostLevelEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeBoostLevelEvent.java new file mode 100644 index 0000000000..311d0dcecb --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeBoostLevelEvent.java @@ -0,0 +1,24 @@ +package org.javacord.api.event.server; + +import org.javacord.api.entity.server.BoostLevel; + +/** + * A server change boost level event. + */ +public interface ServerChangeBoostLevelEvent extends ServerEvent { + + /** + * Gets the old boost level of the server. + * + * @return The old boost level of the server. + */ + BoostLevel getOldBoostLevel(); + + /** + * Gets the new boost level of the server. + * + * @return The new boost level of the server. + */ + BoostLevel getNewBoostLevel(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeDescriptionEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeDescriptionEvent.java new file mode 100644 index 0000000000..9a2f8b2b64 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeDescriptionEvent.java @@ -0,0 +1,24 @@ +package org.javacord.api.event.server; + +import java.util.Optional; + +/** + * A server change description event. + */ +public interface ServerChangeDescriptionEvent extends ServerEvent { + + /** + * Gets the old description of the server. + * + * @return The old description of the server. + */ + Optional getOldDescription(); + + /** + * Gets the new description of the server. + * + * @return The new description of the server. + */ + Optional getNewDescription(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeDiscoverySplashEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeDiscoverySplashEvent.java new file mode 100644 index 0000000000..bcade15be7 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeDiscoverySplashEvent.java @@ -0,0 +1,26 @@ +package org.javacord.api.event.server; + +import org.javacord.api.entity.Icon; + +import java.util.Optional; + +/** + * A server change discovery splash event. + */ +public interface ServerChangeDiscoverySplashEvent extends ServerEvent { + + /** + * Gets the old discovery splash of the server. + * + * @return The old discovery splash of the server. + */ + Optional getOldDiscoverySplash(); + + /** + * Gets the new discovery splash of the server. + * + * @return The new discovery splash of the server. + */ + Optional getNewDiscoverySplash(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeModeratorsOnlyChannelEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeModeratorsOnlyChannelEvent.java new file mode 100644 index 0000000000..f1df731c13 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeModeratorsOnlyChannelEvent.java @@ -0,0 +1,25 @@ +package org.javacord.api.event.server; + +import org.javacord.api.entity.channel.ServerTextChannel; + +import java.util.Optional; + +/** + * A server change moderators-only channel event. + */ +public interface ServerChangeModeratorsOnlyChannelEvent extends ServerEvent { + + /** + * Gets the old moderators-only channel of the server. + * + * @return The old moderators-only channel of the server. + */ + Optional getOldModeratorsOnlyChannel(); + + /** + * Gets the new moderators-only channel of the server. + * + * @return The new moderators-only channel of the server. + */ + Optional getNewModeratorsOnlyChannel(); +} diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangePreferredLocaleEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangePreferredLocaleEvent.java new file mode 100644 index 0000000000..4dccdaa0e8 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangePreferredLocaleEvent.java @@ -0,0 +1,24 @@ +package org.javacord.api.event.server; + +import java.util.Locale; + +/** + * A server change preferred locale event. + */ +public interface ServerChangePreferredLocaleEvent extends ServerEvent { + + /** + * Gets the old preferred locale of the server. + * + * @return The old preferred locale of the server. + */ + Locale getOldPreferredLocale(); + + /** + * Gets the new preferred locale of the server. + * + * @return The new preferred locale of the server. + */ + Locale getNewPreferredLocale(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeRulesChannelEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeRulesChannelEvent.java new file mode 100644 index 0000000000..8c22850750 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeRulesChannelEvent.java @@ -0,0 +1,26 @@ +package org.javacord.api.event.server; + +import org.javacord.api.entity.channel.ServerTextChannel; + +import java.util.Optional; + +/** + * A server change rules channel event. + */ +public interface ServerChangeRulesChannelEvent { + + /** + * Gets the old rules channel of the server. + * + * @return The old rules channel of the server. + */ + Optional getOldRulesChannel(); + + /** + * Gets the new rules channel of the server. + * + * @return The new rules channel of the server. + */ + Optional getNewRulesChannel(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeServerFeaturesEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeServerFeaturesEvent.java new file mode 100644 index 0000000000..66267b9c7a --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeServerFeaturesEvent.java @@ -0,0 +1,26 @@ +package org.javacord.api.event.server; + +import org.javacord.api.entity.server.ServerFeature; + +import java.util.Collection; + +/** + * A server change server features event. + */ +public interface ServerChangeServerFeaturesEvent extends ServerEvent { + + /** + * Gets the old server features of the server. + * + * @return The old server features of the server. + */ + Collection getOldServerFeatures(); + + /** + * Gets the new server features of the server. + * + * @return The new server features of the server. + */ + Collection getNewServerFeatures(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeVanityUrlCodeEvent.java b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeVanityUrlCodeEvent.java new file mode 100644 index 0000000000..d65c39b104 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/event/server/ServerChangeVanityUrlCodeEvent.java @@ -0,0 +1,26 @@ +package org.javacord.api.event.server; + +import org.javacord.api.entity.VanityUrlCode; + +import java.util.Optional; + +/** + * A server change vanity url code event. + */ +public interface ServerChangeVanityUrlCodeEvent extends ServerEvent { + + /** + * Gets the old vanity url code of the server. + * + * @return The old vanity url code of the server. + */ + Optional getOldVanityUrlCode(); + + /** + * Gets the new vanity url code of the server. + * + * @return The new vanity url code of the server. + */ + Optional getNewVanityUrlCode(); + +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeBoostCountListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeBoostCountListener.java new file mode 100644 index 0000000000..e2825f8bc8 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeBoostCountListener.java @@ -0,0 +1,19 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangeBoostCountEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server boost count changes. + */ +@FunctionalInterface +public interface ServerChangeBoostCountListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + /** + * This method is called every time a server's boost count changed. + * + * @param event The event. + */ + void onServerChangeBoostCount(ServerChangeBoostCountEvent event); +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeBoostLevelListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeBoostLevelListener.java new file mode 100644 index 0000000000..ed177b46cb --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeBoostLevelListener.java @@ -0,0 +1,19 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangeBoostLevelEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server boost level changes. + */ +@FunctionalInterface +public interface ServerChangeBoostLevelListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + /** + * This method is called every time a server's boost level changed. + * + * @param event The event. + */ + void onServerChangeBoostLevel(ServerChangeBoostLevelEvent event); +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeDescriptionListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeDescriptionListener.java new file mode 100644 index 0000000000..e2a0a3eb06 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeDescriptionListener.java @@ -0,0 +1,19 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangeDescriptionEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server description changes. + */ +@FunctionalInterface +public interface ServerChangeDescriptionListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + /** + * This method is called every time a server's description changed. + * + * @param event The event. + */ + void onServerChangeDescription(ServerChangeDescriptionEvent event); +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeDiscoverySplashListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeDiscoverySplashListener.java new file mode 100644 index 0000000000..22ab10d1eb --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeDiscoverySplashListener.java @@ -0,0 +1,19 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangeDiscoverySplashEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server discovery splash changes. + */ +@FunctionalInterface +public interface ServerChangeDiscoverySplashListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + /** + * This method is called every time a server's discovery splash changed. + * + * @param event The event. + */ + void onServerChangeDiscoverySplash(ServerChangeDiscoverySplashEvent event); +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeModeratorsOnlyChannelListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeModeratorsOnlyChannelListener.java new file mode 100644 index 0000000000..9bc2be1859 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeModeratorsOnlyChannelListener.java @@ -0,0 +1,20 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangeModeratorsOnlyChannelEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server moderators-only channel changes. + */ +@FunctionalInterface +public interface ServerChangeModeratorsOnlyChannelListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + + /** + * This method is called every time a server's moderators-only channel changed. + * + * @param event The event. + */ + void onServerChangeModeratorsOnlyChannel(ServerChangeModeratorsOnlyChannelEvent event); +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangePreferredLocaleListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangePreferredLocaleListener.java new file mode 100644 index 0000000000..52c4476ade --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangePreferredLocaleListener.java @@ -0,0 +1,19 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangePreferredLocaleEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server preferred locale changes. + */ +@FunctionalInterface +public interface ServerChangePreferredLocaleListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + /** + * This method is called every time a server's preferred locale changed. + * + * @param event The event. + */ + void onServerChangePreferredLocale(ServerChangePreferredLocaleEvent event); +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeRulesChannelListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeRulesChannelListener.java new file mode 100644 index 0000000000..79242dca92 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeRulesChannelListener.java @@ -0,0 +1,20 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangeRulesChannelEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server rules channel changes. + */ +@FunctionalInterface +public interface ServerChangeRulesChannelListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + + /** + * This method is called every time a server's rules channel changed. + * + * @param event The event. + */ + void onServerChangeRulesChannel(ServerChangeRulesChannelEvent event); +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeServerFeatureListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeServerFeatureListener.java new file mode 100644 index 0000000000..ee3c93655a --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeServerFeatureListener.java @@ -0,0 +1,20 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangeServerFeaturesEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server feature changes. + */ +@FunctionalInterface +public interface ServerChangeServerFeatureListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + + /** + * This method is called every time a server's feature changed. + * + * @param event The event. + */ + void onServerChangeServerFeature(ServerChangeServerFeaturesEvent event); +} diff --git a/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeVanityUrlCodeListener.java b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeVanityUrlCodeListener.java new file mode 100644 index 0000000000..d6a3864115 --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/listener/server/ServerChangeVanityUrlCodeListener.java @@ -0,0 +1,20 @@ +package org.javacord.api.listener.server; + +import org.javacord.api.event.server.ServerChangeVanityUrlCodeEvent; +import org.javacord.api.listener.GloballyAttachableListener; +import org.javacord.api.listener.ObjectAttachableListener; + +/** + * This listener listens to server vanity url code changes. + */ +@FunctionalInterface +public interface ServerChangeVanityUrlCodeListener extends ServerAttachableListener, GloballyAttachableListener, + ObjectAttachableListener { + + /** + * This method is called every time a server's vanity url code changed. + * + * @param event The event. + */ + void onServerChangeVanityUrlCode(ServerChangeVanityUrlCodeEvent event); +} diff --git a/javacord-core/src/main/java/org/javacord/core/entity/VanityUrlCodeImpl.java b/javacord-core/src/main/java/org/javacord/core/entity/VanityUrlCodeImpl.java new file mode 100644 index 0000000000..3bd3e026f1 --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/entity/VanityUrlCodeImpl.java @@ -0,0 +1,35 @@ +package org.javacord.core.entity; + +import org.javacord.api.entity.VanityUrlCode; + +import java.net.MalformedURLException; +import java.net.URL; + +public class VanityUrlCodeImpl implements VanityUrlCode { + + private final String code; + + /** + * Creates a new VanityUrlCode. + * + * @param vanityUrlCode The vanity code + */ + public VanityUrlCodeImpl(String vanityUrlCode) { + code = vanityUrlCode; + } + + @Override + public String getCode() { + return code; + } + + @Override + public URL getUrl() { + try { + return new URL("https://discord.com/invite/" + code); + } catch (MalformedURLException e) { + throw new AssertionError("Unexpected malformed vanity url", e); + } + } + +} diff --git a/javacord-core/src/main/java/org/javacord/core/entity/server/ServerImpl.java b/javacord-core/src/main/java/org/javacord/core/entity/server/ServerImpl.java index 773e9833f7..4a571b5126 100644 --- a/javacord-core/src/main/java/org/javacord/core/entity/server/ServerImpl.java +++ b/javacord-core/src/main/java/org/javacord/core/entity/server/ServerImpl.java @@ -11,6 +11,7 @@ import org.javacord.api.entity.DiscordEntity; import org.javacord.api.entity.Icon; import org.javacord.api.entity.Region; +import org.javacord.api.entity.VanityUrlCode; import org.javacord.api.entity.activity.Activity; import org.javacord.api.entity.auditlog.AuditLog; import org.javacord.api.entity.auditlog.AuditLogActionType; @@ -23,10 +24,12 @@ import org.javacord.api.entity.emoji.KnownCustomEmoji; import org.javacord.api.entity.permission.Role; import org.javacord.api.entity.server.Ban; +import org.javacord.api.entity.server.BoostLevel; import org.javacord.api.entity.server.DefaultMessageNotificationLevel; import org.javacord.api.entity.server.ExplicitContentFilterLevel; import org.javacord.api.entity.server.MultiFactorAuthenticationLevel; import org.javacord.api.entity.server.Server; +import org.javacord.api.entity.server.ServerFeature; import org.javacord.api.entity.server.VerificationLevel; import org.javacord.api.entity.server.invite.RichInvite; import org.javacord.api.entity.user.User; @@ -34,6 +37,7 @@ import org.javacord.api.entity.webhook.Webhook; import org.javacord.core.DiscordApiImpl; import org.javacord.core.entity.IconImpl; +import org.javacord.core.entity.VanityUrlCodeImpl; import org.javacord.core.entity.activity.ActivityImpl; import org.javacord.core.entity.auditlog.AuditLogImpl; import org.javacord.core.entity.channel.ChannelCategoryImpl; @@ -63,6 +67,7 @@ import java.util.Comparator; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -228,10 +233,64 @@ public class ServerImpl implements Server, Cleanupable, InternalServerAttachable */ private final Collection customEmojis = new ArrayList<>(); + /** + * A list with all features from this server. + */ + private final Collection serverFeatures = new ArrayList<>(); + + /** + * The premium tier level of the server. + */ + private volatile BoostLevel boostLevel; + + /** + * The server's premium subscription count. + */ + private volatile int serverBoostCount = 0; + + /** + * The server's rules channel id. + */ + private volatile long rulesChannelId = -1; + /** + * The servers description. + */ + private volatile String description; + + /** + * The id of the server's moderators-only channel. + */ + private volatile long moderatorsOnlyChannelId = -1; + + /** + * The servers preferred locale. + */ + private volatile Locale preferredLocale; + + /** + * The servers vanity. + */ + private volatile VanityUrlCode vanityUrlCode; + + /** + * The discovery splash of the server. Might be null. + */ + private volatile String discoverySplash; + + /** + * Whether the server has join messages enabled. + */ + private volatile boolean hasJoinMessagesEnabled = true; + + /** + * Whether the server has boost messages enabled. + */ + private volatile boolean hasBoostMessagesEnabled = true; + /** * Creates a new server object. * - * @param api The discord api instance. + * @param api The discord api instance. * @param data The json data of the server. */ public ServerImpl(DiscordApiImpl api, JsonNode data) { @@ -248,6 +307,8 @@ public ServerImpl(DiscordApiImpl api, JsonNode data) { defaultMessageNotificationLevel = DefaultMessageNotificationLevel.fromId(data.get("default_message_notifications").asInt()); multiFactorAuthenticationLevel = MultiFactorAuthenticationLevel.fromId(data.get("mfa_level").asInt()); + boostLevel = BoostLevel.fromId(data.get("premium_tier").asInt()); + preferredLocale = new Locale.Builder().setLanguageTag(data.get("preferred_locale").asText()).build(); if (data.has("icon") && !data.get("icon").isNull()) { iconHash = data.get("icon").asText(); } @@ -266,6 +327,30 @@ public ServerImpl(DiscordApiImpl api, JsonNode data) { if (data.hasNonNull("application_id")) { applicationId = data.get("application_id").asLong(); } + if (data.has("features")) { + data.get("features").forEach(jsonNode -> addFeature(jsonNode.asText())); + } + if (data.has("premium_subscription_count")) { + serverBoostCount = data.get("premium_subscription_count").asInt(); + } + if (data.hasNonNull("rules_channel_id")) { + rulesChannelId = data.get("rules_channel_id").asLong(); + } + if (data.hasNonNull("description")) { + description = data.get("description").asText(); + } + if (data.hasNonNull("public_updates_channel_id")) { + moderatorsOnlyChannelId = data.get("public_updates_channel_id").asLong(); + } + if (data.hasNonNull("discovery_splash")) { + discoverySplash = data.get("discovery_splash").asText(); + } + if (data.hasNonNull("vanity_url_code")) { + vanityUrlCode = new VanityUrlCodeImpl(data.get("vanity_url_code").asText()); + } + if (data.hasNonNull("system_channel_flags")) { + setSystemChannelFlag(data.get("system_channel_flags").asInt()); + } if (data.has("channels")) { for (JsonNode channel : data.get("channels")) { @@ -371,6 +456,31 @@ public ServerImpl(DiscordApiImpl api, JsonNode data) { api.addServerToCache(this); } + /** + * Sets the system channel flags. + * + * @param value The system channel flag. + */ + public void setSystemChannelFlag(int value) { + hasJoinMessagesEnabled = (value & (1)) != (1); + hasBoostMessagesEnabled = (value & (1 << 1)) != (1 << 1); + } + + /** + * Adds the feature to the collection. + * + * @param feature The feature to add. + */ + private void addFeature(String feature) { + try { + serverFeatures.add(ServerFeature.valueOf(feature)); + } catch (Exception ignored) { + logger.debug("Encountered server with unknown feature {}. Please update to the latest " + + "Javacord version or create an issue on the Javacord GitHub page if you are " + + "already on the latest version.", feature); + } + } + /** * Checks if the server is ready (all members are cached). * @@ -716,7 +826,7 @@ public void incrementMemberCount() { /** * Sets the nickname of the user. * - * @param user The user. + * @param user The user. * @param nickname The nickname to set. */ public void setNickname(User user, String nickname) { @@ -727,7 +837,7 @@ public void setNickname(User user, String nickname) { * Sets the self-muted state of the user with the given id. * * @param userId The id of the user. - * @param muted Whether the user with the given id is self-muted or not. + * @param muted Whether the user with the given id is self-muted or not. */ public void setSelfMuted(long userId, boolean muted) { if (muted) { @@ -740,7 +850,7 @@ public void setSelfMuted(long userId, boolean muted) { /** * Sets the self-deafened state of the user with the given id. * - * @param userId The id of the user. + * @param userId The id of the user. * @param deafened Whether the user with the given id is self-deafened or not. */ public void setSelfDeafened(long userId, boolean deafened) { @@ -755,7 +865,7 @@ public void setSelfDeafened(long userId, boolean deafened) { * Sets the muted state of the user with the given id. * * @param userId The id of the user. - * @param muted Whether the user with the given id is muted or not. + * @param muted Whether the user with the given id is muted or not. */ public void setMuted(long userId, boolean muted) { if (muted) { @@ -768,7 +878,7 @@ public void setMuted(long userId, boolean muted) { /** * Sets the deafened state of the user with the given id. * - * @param userId The id of the user. + * @param userId The id of the user. * @param deafened Whether the user with the given id is deafened or not. */ public void setDeafened(long userId, boolean deafened) { @@ -799,6 +909,97 @@ public void setName(String name) { this.name = name; } + /** + * Sets the rules channel of the server. + * + * @param rulesChannelId The rules channel of the server. + */ + public void setRulesChannelId(long rulesChannelId) { + this.rulesChannelId = rulesChannelId; + } + + /** + * Sets the moderators-only channel of the server. + * + * @param moderatorsOnlyChannelId The moderators-only channel of the server. + */ + public void setModeratorsOnlyChannelId(long moderatorsOnlyChannelId) { + this.moderatorsOnlyChannelId = moderatorsOnlyChannelId; + } + + /** + * Sets the boost level of the server. + * + * @param boostLevel The boost level of the server. + */ + public void setBoostLevel(BoostLevel boostLevel) { + this.boostLevel = boostLevel; + } + + /** + * Sets the preferred locale of the server. + * + * @param preferredLocale The preferred locale of the server. + */ + public void setPreferredLocale(Locale preferredLocale) { + this.preferredLocale = preferredLocale; + } + + /** + * Sets the server boost count of the server. + * + * @param serverBoostCount The server boost count of the server. + */ + public void setServerBoostCount(int serverBoostCount) { + this.serverBoostCount = serverBoostCount; + } + + /** + * Sets the description of the server. + * + * @param description The description of the server. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Sets the discovery splash hash of the server. + * + * @param discoverySplashHash The discovery splash hash of the server. + */ + public void setDiscoverySplashHash(String discoverySplashHash) { + discoverySplash = discoverySplashHash; + } + + /** + * Gets the discovery splash hash of the server. + * + * @return The discovery splash hash of the server. + */ + public String getDiscoverySplashHash() { + return discoverySplash; + } + + /** + * Sets the vanity url code of the server. + * + * @param vanityUrlCode The vanity url code of the server. + */ + public void setVanityUrlCode(VanityUrlCode vanityUrlCode) { + this.vanityUrlCode = vanityUrlCode; + } + + /** + * Sets the server feature of the server. + * + * @param serverFeatures The server feature of the server. + */ + public void setServerFeatures(Collection serverFeatures) { + this.serverFeatures.clear(); + this.serverFeatures.addAll(serverFeatures); + } + /** * Gets an unordered collection with all channels in the server. * @@ -823,6 +1024,70 @@ public String getName() { return name; } + @Override + public boolean hasBoostMessagesEnabled() { + return hasBoostMessagesEnabled; + } + + @Override + public boolean hasJoinMessagesEnabled() { + return hasJoinMessagesEnabled; + } + + @Override + public Collection getFeatures() { + return Collections.unmodifiableCollection(new HashSet<>(serverFeatures)); + } + + @Override + public BoostLevel getBoostLevel() { + return boostLevel; + } + + @Override + public int getBoostCount() { + return serverBoostCount; + } + + @Override + public Optional getRulesChannel() { + return getTextChannelById(rulesChannelId); + } + + @Override + public Optional getDescription() { + return Optional.ofNullable(description); + } + + @Override + public Optional getModeratorsOnlyChannel() { + return getTextChannelById(moderatorsOnlyChannelId); + } + + @Override + public Optional getVanityUrlCode() { + return Optional.ofNullable(vanityUrlCode); + } + + @Override + public Optional getDiscoverySplash() { + if (splash == null) { + return Optional.empty(); + } + try { + return Optional.of(new IconImpl( + getApi(), + new URL("https://cdn.discordapp.com/discovery-splashes/" + getIdAsString() + "/" + discoverySplash + ".png"))); + } catch (MalformedURLException e) { + throw new AssertionError("Unexpected malformed discovery splash url", e); + } + } + + @Override + public Locale getPreferredLocale() { + return preferredLocale; + } + @Override public Region getRegion() { return region; @@ -1254,9 +1519,9 @@ public void cleanup() { @Override public boolean equals(Object o) { return (this == o) - || !((o == null) - || (getClass() != o.getClass()) - || (getId() != ((DiscordEntity) o).getId())); + || !((o == null) + || (getClass() != o.getClass()) + || (getId() != ((DiscordEntity) o).getId())); } @Override diff --git a/javacord-core/src/main/java/org/javacord/core/entity/server/ServerUpdaterDelegateImpl.java b/javacord-core/src/main/java/org/javacord/core/entity/server/ServerUpdaterDelegateImpl.java index b810c57b54..9990bedf71 100644 --- a/javacord-core/src/main/java/org/javacord/core/entity/server/ServerUpdaterDelegateImpl.java +++ b/javacord-core/src/main/java/org/javacord/core/entity/server/ServerUpdaterDelegateImpl.java @@ -32,6 +32,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -155,6 +156,46 @@ public class ServerUpdaterDelegateImpl implements ServerUpdaterDelegate { */ private boolean updateSystemChannel = false; + /** + * The banner to update. + */ + private FileContainer banner = null; + + /** + * Whether the banner should be updated or not. + */ + private boolean updateBanner = false; + + /** + * The rules channel to update. + */ + private ServerChannel rulesChannel = null; + + /** + * Whether the rules channel should be updated or not. + */ + private boolean updateRulesChannel = false; + + /** + * The moderators-only channel to update. + */ + private ServerChannel moderatorsOnlyChannel = null; + + /** + * Whether the moderators-only channel should be updated or not. + */ + private boolean updateModeratorsOnlyChannel = false; + + /** + * The locale to be updated. + */ + private Locale locale = null; + + /** + * Whether the locale should be updated or not. + */ + private boolean updateLocale = false; + /** * Creates a new server updater delegate. * @@ -336,6 +377,94 @@ public void removeSplash() { updateSplash = true; } + @Override + public void setBanner(BufferedImage banner) { + this.banner = (banner == null) ? null : new FileContainer(banner, "png"); + updateBanner = true; + } + + @Override + public void setBanner(BufferedImage banner, String fileType) { + this.banner = (banner == null) ? null : new FileContainer(banner, fileType); + updateBanner = true; + } + + @Override + public void setBanner(File banner) { + this.banner = (banner == null) ? null : new FileContainer(banner); + updateBanner = true; + } + + @Override + public void setBanner(Icon banner) { + this.banner = (banner == null) ? null : new FileContainer(banner); + updateBanner = true; + } + + @Override + public void setBanner(URL banner) { + this.banner = (banner == null) ? null : new FileContainer(banner); + updateBanner = true; + } + + @Override + public void setBanner(byte[] banner) { + this.banner = (banner == null) ? null : new FileContainer(banner, "png"); + updateBanner = true; + } + + @Override + public void setBanner(byte[] banner, String fileType) { + this.banner = (banner == null) ? null : new FileContainer(banner, fileType); + updateBanner = true; + } + + @Override + public void setBanner(InputStream banner) { + this.banner = (banner == null) ? null : new FileContainer(banner, "png"); + updateBanner = true; + } + + @Override + public void setBanner(InputStream banner, String fileType) { + this.banner = (banner == null) ? null : new FileContainer(banner, fileType); + updateBanner = true; + } + + @Override + public void removeBanner() { + banner = null; + updateBanner = true; + } + + @Override + public void setRulesChannel(ServerTextChannel rulesChannel) { + this.rulesChannel = rulesChannel; + updateRulesChannel = true; + } + + @Override + public void removeRulesChannel() { + setRulesChannel(null); + } + + @Override + public void setModeratorsOnlyChannel(ServerTextChannel moderatorsOnlyChannel) { + this.moderatorsOnlyChannel = moderatorsOnlyChannel; + updateModeratorsOnlyChannel = true; + } + + @Override + public void removeModeratorsOnlyChannel() { + setModeratorsOnlyChannel(null); + } + + @Override + public void setPreferredLocale(Locale locale) { + this.locale = locale; + updateLocale = true; + } + @Override public void setSystemChannel(ServerTextChannel systemChannel) { this.systemChannel = systemChannel; @@ -539,9 +668,39 @@ public CompletableFuture update() { } patchServer = true; } + if (updateModeratorsOnlyChannel) { + if (moderatorsOnlyChannel != null) { + body.put("public_updates_channel_id", moderatorsOnlyChannel.getIdAsString()); + } else { + body.putNull("public_updates_channel_id"); + } + patchServer = true; + } + if (updateRulesChannel) { + if (rulesChannel != null) { + body.put("rules_channel_id", rulesChannel.getIdAsString()); + } else { + body.putNull("rules_channel_id"); + } + patchServer = true; + } + if (updateBanner) { + if (banner == null) { + body.putNull("banner"); + } + patchServer = true; + } + if (updateLocale) { + if (locale == null) { + body.putNull("preferred_locale"); + } else { + body.put("preferred_locale", locale.toLanguageTag()); + } + patchServer = true; + } // Only make a REST call, if we really want to update something if (patchServer) { - if (icon != null || splash != null) { + if (icon != null || splash != null || banner != null) { CompletableFuture iconFuture = null; if (icon != null) { iconFuture = icon.asByteArray(server.getApi()).thenAccept(bytes -> { @@ -558,14 +717,27 @@ public CompletableFuture update() { body.put("splash", base64Splash); }); } + CompletableFuture bannerFuture = null; + if (banner != null) { + bannerFuture = banner.asByteArray(server.getApi()).thenAccept(bytes -> { + String base64Banner = "data:image/" + banner.getFileType() + ";base64," + + Base64.getEncoder().encodeToString(bytes); + body.put("banner", base64Banner); + }); + } CompletableFuture future; - if (iconFuture == null) { - future = splashFuture; - } else if (splashFuture == null) { - future = iconFuture; - } else { - future = CompletableFuture.allOf(splashFuture, iconFuture); + List> futureList = new ArrayList<>(); + if (iconFuture != null) { + futureList.add(iconFuture); + } + if (splashFuture != null) { + futureList.add(splashFuture); } + if (bannerFuture != null) { + futureList.add(bannerFuture); + } + future = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])); + tasks.add(future.thenCompose( aVoid -> new RestRequest(server.getApi(), RestMethod.PATCH, RestEndpoint.SERVER) .setUrlParameters(server.getIdAsString()) diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeBoostCountEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeBoostCountEventImpl.java new file mode 100644 index 0000000000..5ea73d30b9 --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeBoostCountEventImpl.java @@ -0,0 +1,43 @@ +package org.javacord.core.event.server; + +import org.javacord.api.event.server.ServerChangeBoostCountEvent; +import org.javacord.core.entity.server.ServerImpl; + +/** + * The implementation of {@link ServerChangeBoostCountEvent}. + */ +public class ServerChangeBoostCountEventImpl extends ServerEventImpl implements ServerChangeBoostCountEvent { + + /** + * The old boost count of the server. + */ + private final int oldBoostCount; + + /** + * The new boost count of the server. + */ + private final int newBoostCount; + + /** + * Creates a new boost count change event. + * + * @param server The server of the event. + * @param newBoostCount The new boost count of the server. + * @param oldBoostCount The old boost count of the server. + */ + public ServerChangeBoostCountEventImpl(ServerImpl server, int newBoostCount, int oldBoostCount) { + super(server); + this.oldBoostCount = oldBoostCount; + this.newBoostCount = newBoostCount; + } + + @Override + public int getOldBoostCount() { + return oldBoostCount; + } + + @Override + public int getNewBoostCount() { + return newBoostCount; + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeBoostLevelEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeBoostLevelEventImpl.java new file mode 100644 index 0000000000..4e22e48b66 --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeBoostLevelEventImpl.java @@ -0,0 +1,44 @@ +package org.javacord.core.event.server; + +import org.javacord.api.entity.server.BoostLevel; +import org.javacord.api.event.server.ServerChangeBoostLevelEvent; +import org.javacord.core.entity.server.ServerImpl; + +/** + * The implementation of {@link ServerChangeBoostLevelEvent}. + */ +public class ServerChangeBoostLevelEventImpl extends ServerEventImpl implements ServerChangeBoostLevelEvent { + + /** + * The old boost level of the server. + */ + private final BoostLevel oldBoostLevel; + + /** + * The new boost level of the server. + */ + private final BoostLevel newBoostLevel; + + /** + * Creates a new boost level change event. + * + * @param server The server of the event. + * @param newBoostLevel The new boost level of the server. + * @param oldBoostLevel The old boost level of the server. + */ + public ServerChangeBoostLevelEventImpl(ServerImpl server, BoostLevel newBoostLevel, BoostLevel oldBoostLevel) { + super(server); + this.oldBoostLevel = oldBoostLevel; + this.newBoostLevel = newBoostLevel; + } + + @Override + public BoostLevel getOldBoostLevel() { + return oldBoostLevel; + } + + @Override + public BoostLevel getNewBoostLevel() { + return newBoostLevel; + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeDescriptionEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeDescriptionEventImpl.java new file mode 100644 index 0000000000..3b70057613 --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeDescriptionEventImpl.java @@ -0,0 +1,45 @@ +package org.javacord.core.event.server; + +import org.javacord.api.event.server.ServerChangeDescriptionEvent; +import org.javacord.core.entity.server.ServerImpl; + +import java.util.Optional; + +/** + * The implementation of {@link ServerChangeDescriptionEvent}. + */ +public class ServerChangeDescriptionEventImpl extends ServerEventImpl implements ServerChangeDescriptionEvent { + + /** + * The old description of the server. + */ + private final String oldDescription; + + /** + * The new description of the server. + */ + private final String newDescription; + + /** + * Creates a new description change event. + * + * @param server The server of the event. + * @param newDescription The new description of the server. + * @param oldDescription The old description of the server. + */ + public ServerChangeDescriptionEventImpl(ServerImpl server, String newDescription, String oldDescription) { + super(server); + this.newDescription = newDescription; + this.oldDescription = oldDescription; + } + + @Override + public Optional getOldDescription() { + return Optional.ofNullable(oldDescription); + } + + @Override + public Optional getNewDescription() { + return Optional.ofNullable(newDescription); + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeDiscoverySplashEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeDiscoverySplashEventImpl.java new file mode 100644 index 0000000000..ac80eb786c --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeDiscoverySplashEventImpl.java @@ -0,0 +1,76 @@ +package org.javacord.core.event.server; + +import org.apache.logging.log4j.Logger; +import org.javacord.api.entity.Icon; +import org.javacord.api.event.server.ServerChangeDiscoverySplashEvent; +import org.javacord.core.entity.IconImpl; +import org.javacord.core.entity.server.ServerImpl; +import org.javacord.core.util.logging.LoggerUtil; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Optional; + +/** + * The implementation of {@link ServerChangeDiscoverySplashEvent}. + */ +public class ServerChangeDiscoverySplashEventImpl extends ServerEventImpl implements ServerChangeDiscoverySplashEvent { + + /** + * The logger of this class. + */ + private static final Logger logger = LoggerUtil.getLogger(ServerChangeDiscoverySplashEvent.class); + + /** + * The old discovery splash hash of the server. + */ + private final String oldDiscoverySplashHash; + + /** + * The new discovery splash hash of the server. + */ + private final String newDiscoverySplashHash; + + /** + * Creates a new discovery splash hash change event. + * + * @param server The server of the event. + * @param newDiscoverySplashHash The new discovery splash hash of the server. + * @param oldDiscoverySplashHash The old discovery splash hash of the server. + */ + public ServerChangeDiscoverySplashEventImpl(ServerImpl server, + String newDiscoverySplashHash, String oldDiscoverySplashHash) { + super(server); + this.oldDiscoverySplashHash = oldDiscoverySplashHash; + this.newDiscoverySplashHash = newDiscoverySplashHash; + } + + @Override + public Optional getOldDiscoverySplash() { + return getDiscoverySplash(oldDiscoverySplashHash); + } + + @Override + public Optional getNewDiscoverySplash() { + return getDiscoverySplash(newDiscoverySplashHash); + } + + /** + * Gets the discovery splash for the given hash. + * + * @param discoverySplashHash The hash of the discovery splash. + * @return The discovery splash with the given hash. + */ + private Optional getDiscoverySplash(String discoverySplashHash) { + if (discoverySplashHash == null) { + return Optional.empty(); + } + try { + return Optional.of(new IconImpl(getApi(), + new URL("https://cdn.discordapp.com/discovery-splashes/" + getServer().getIdAsString() + + "/" + discoverySplashHash + ".png"))); + } catch (MalformedURLException e) { + throw new AssertionError("Failed to create discovery splash url", e); + } + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeModeratorsOnlyChannelEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeModeratorsOnlyChannelEventImpl.java new file mode 100644 index 0000000000..87c402a823 --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeModeratorsOnlyChannelEventImpl.java @@ -0,0 +1,50 @@ +package org.javacord.core.event.server; + +import org.javacord.api.entity.channel.ServerTextChannel; +import org.javacord.api.event.server.ServerChangeModeratorsOnlyChannelEvent; +import org.javacord.core.entity.server.ServerImpl; + +import java.util.Optional; + +/** + * The implementation of {@link ServerChangeModeratorsOnlyChannelEvent}. + */ +public class ServerChangeModeratorsOnlyChannelEventImpl + extends ServerEventImpl implements ServerChangeModeratorsOnlyChannelEvent { + + /** + * The new moderators-only channel of the server. + */ + private final ServerTextChannel newModeratorsOnlyChannel; + + /** + * The old moderator-only channel of the server. + */ + private final ServerTextChannel oldModeratorsOnlyChannel; + + /** + * Creates a new moderators-only channel change event. + * + * @param server The server of the event. + * @param newModeratorsOnlyChannel The new moderators-only channel of the server. + * @param oldModeratorsOnlyChannel The old moderators-only updates channel of the server. + */ + public ServerChangeModeratorsOnlyChannelEventImpl(ServerImpl server, + ServerTextChannel newModeratorsOnlyChannel, + ServerTextChannel oldModeratorsOnlyChannel) { + super(server); + this.newModeratorsOnlyChannel = newModeratorsOnlyChannel; + this.oldModeratorsOnlyChannel = oldModeratorsOnlyChannel; + } + + + @Override + public Optional getOldModeratorsOnlyChannel() { + return Optional.ofNullable(oldModeratorsOnlyChannel); + } + + @Override + public Optional getNewModeratorsOnlyChannel() { + return Optional.ofNullable(newModeratorsOnlyChannel); + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangePreferredLocaleEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangePreferredLocaleEventImpl.java new file mode 100644 index 0000000000..a7e2d70190 --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangePreferredLocaleEventImpl.java @@ -0,0 +1,45 @@ +package org.javacord.core.event.server; + +import org.javacord.api.event.server.ServerChangePreferredLocaleEvent; +import org.javacord.core.entity.server.ServerImpl; + +import java.util.Locale; + +/** + * The implementation of {@link ServerChangePreferredLocaleEvent}. + */ +public class ServerChangePreferredLocaleEventImpl extends ServerEventImpl implements ServerChangePreferredLocaleEvent { + + /** + * The new preferred locale of the server. + */ + private final Locale newPreferredLocale; + /** + * The old preferred locale of the server. + */ + private final Locale oldPreferredLocale; + + /** + * Creates a new preferred locale change event. + * + * @param server The server of the event. + * @param oldPreferredLocale The new preferred locale of the server. + * @param newPreferredLocale The old preferred locale of the server. + */ + public ServerChangePreferredLocaleEventImpl(ServerImpl server, + Locale newPreferredLocale, Locale oldPreferredLocale) { + super(server); + this.oldPreferredLocale = oldPreferredLocale; + this.newPreferredLocale = newPreferredLocale; + } + + @Override + public Locale getOldPreferredLocale() { + return oldPreferredLocale; + } + + @Override + public Locale getNewPreferredLocale() { + return newPreferredLocale; + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeRulesChannelEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeRulesChannelEventImpl.java new file mode 100644 index 0000000000..97e79b1adb --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeRulesChannelEventImpl.java @@ -0,0 +1,45 @@ +package org.javacord.core.event.server; + +import org.javacord.api.entity.channel.ServerTextChannel; +import org.javacord.api.event.server.ServerChangeRulesChannelEvent; +import org.javacord.core.entity.server.ServerImpl; + +import java.util.Optional; + +/** + * The implementation of {@link ServerChangeRulesChannelEvent}. + */ +public class ServerChangeRulesChannelEventImpl extends ServerEventImpl implements ServerChangeRulesChannelEvent { + /** + * The old rules channel of the server. + */ + private final ServerTextChannel oldRulesChannel; + /** + * The new rules channel of the server. + */ + private final ServerTextChannel newRulesChannel; + + /** + * Creates a new rules channel change event. + * + * @param server The server of the event. + * @param newRulesChannel The new rules channel of the server. + * @param oldRulesChannel The old rules channel of the server. + */ + public ServerChangeRulesChannelEventImpl(ServerImpl server, + ServerTextChannel newRulesChannel, ServerTextChannel oldRulesChannel) { + super(server); + this.newRulesChannel = newRulesChannel; + this.oldRulesChannel = oldRulesChannel; + } + + @Override + public Optional getOldRulesChannel() { + return Optional.ofNullable(oldRulesChannel); + } + + @Override + public Optional getNewRulesChannel() { + return Optional.ofNullable(newRulesChannel); + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeServerFeaturesEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeServerFeaturesEventImpl.java new file mode 100644 index 0000000000..33347227e2 --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeServerFeaturesEventImpl.java @@ -0,0 +1,49 @@ +package org.javacord.core.event.server; + +import org.javacord.api.entity.server.ServerFeature; +import org.javacord.api.event.server.ServerChangeServerFeaturesEvent; +import org.javacord.core.entity.server.ServerImpl; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; + +/** + * The implementation of {@link ServerChangeServerFeaturesEvent}. + */ +public class ServerChangeServerFeaturesEventImpl extends ServerEventImpl implements ServerChangeServerFeaturesEvent { + + /** + * The new server feature of the server. + */ + private final Collection newServerFeature; + /** + * The old server feature of the server. + */ + private final Collection oldServerFeature; + + /** + * Creates a new server feature change event. + * + * @param server The server of the event. + * @param newServerFeature The new server feature of the server. + * @param oldServerFeature The old server feature of the server. + */ + public ServerChangeServerFeaturesEventImpl(ServerImpl server, + Collection newServerFeature, + Collection oldServerFeature) { + super(server); + this.oldServerFeature = oldServerFeature; + this.newServerFeature = newServerFeature; + } + + @Override + public Collection getOldServerFeatures() { + return Collections.unmodifiableCollection(new HashSet<>(oldServerFeature)); + } + + @Override + public Collection getNewServerFeatures() { + return Collections.unmodifiableCollection(new HashSet<>(newServerFeature)); + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeVanityUrlCodeEventImpl.java b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeVanityUrlCodeEventImpl.java new file mode 100644 index 0000000000..4e7370d9cf --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/event/server/ServerChangeVanityUrlCodeEventImpl.java @@ -0,0 +1,47 @@ +package org.javacord.core.event.server; + +import org.javacord.api.entity.VanityUrlCode; +import org.javacord.api.event.server.ServerChangeVanityUrlCodeEvent; +import org.javacord.core.entity.VanityUrlCodeImpl; +import org.javacord.core.entity.server.ServerImpl; + +import java.util.Optional; + +/** + * The implementation of {@link ServerChangeVanityUrlCodeEvent}. + */ +public class ServerChangeVanityUrlCodeEventImpl extends ServerEventImpl implements ServerChangeVanityUrlCodeEvent { + + /** + * The new vanity url code of the server. + */ + private final String newVanityUrlCode; + + /** + * The old vanity url code of the server. + */ + private final String oldVanityCode; + + /** + * Creates a new vanity url code change event. + * + * @param server The server of the event. + * @param newVanityCode The new vanity url code of the server. + * @param oldVanityCode The old vanity url code of the server. + */ + public ServerChangeVanityUrlCodeEventImpl(ServerImpl server, String newVanityCode, String oldVanityCode) { + super(server); + this.oldVanityCode = oldVanityCode; + this.newVanityUrlCode = newVanityCode; + } + + @Override + public Optional getOldVanityUrlCode() { + return Optional.ofNullable(oldVanityCode == null ? null : new VanityUrlCodeImpl(oldVanityCode)); + } + + @Override + public Optional getNewVanityUrlCode() { + return Optional.ofNullable(newVanityUrlCode == null ? null : new VanityUrlCodeImpl(newVanityUrlCode)); + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/util/handler/guild/GuildUpdateHandler.java b/javacord-core/src/main/java/org/javacord/core/util/handler/guild/GuildUpdateHandler.java index d3e67b5c8f..2f8e8b5c32 100644 --- a/javacord-core/src/main/java/org/javacord/core/util/handler/guild/GuildUpdateHandler.java +++ b/javacord-core/src/main/java/org/javacord/core/util/handler/guild/GuildUpdateHandler.java @@ -1,42 +1,69 @@ package org.javacord.core.util.handler.guild; import com.fasterxml.jackson.databind.JsonNode; +import org.apache.logging.log4j.Logger; import org.javacord.api.DiscordApi; import org.javacord.api.entity.Region; +import org.javacord.api.entity.VanityUrlCode; import org.javacord.api.entity.channel.ServerTextChannel; import org.javacord.api.entity.channel.ServerVoiceChannel; +import org.javacord.api.entity.server.BoostLevel; import org.javacord.api.entity.server.DefaultMessageNotificationLevel; import org.javacord.api.entity.server.ExplicitContentFilterLevel; import org.javacord.api.entity.server.MultiFactorAuthenticationLevel; +import org.javacord.api.entity.server.ServerFeature; import org.javacord.api.entity.server.VerificationLevel; import org.javacord.api.entity.user.User; import org.javacord.api.event.server.ServerChangeAfkChannelEvent; import org.javacord.api.event.server.ServerChangeAfkTimeoutEvent; +import org.javacord.api.event.server.ServerChangeBoostCountEvent; +import org.javacord.api.event.server.ServerChangeBoostLevelEvent; import org.javacord.api.event.server.ServerChangeDefaultMessageNotificationLevelEvent; +import org.javacord.api.event.server.ServerChangeDescriptionEvent; +import org.javacord.api.event.server.ServerChangeDiscoverySplashEvent; import org.javacord.api.event.server.ServerChangeExplicitContentFilterLevelEvent; import org.javacord.api.event.server.ServerChangeIconEvent; +import org.javacord.api.event.server.ServerChangeModeratorsOnlyChannelEvent; import org.javacord.api.event.server.ServerChangeMultiFactorAuthenticationLevelEvent; import org.javacord.api.event.server.ServerChangeNameEvent; import org.javacord.api.event.server.ServerChangeOwnerEvent; +import org.javacord.api.event.server.ServerChangePreferredLocaleEvent; import org.javacord.api.event.server.ServerChangeRegionEvent; +import org.javacord.api.event.server.ServerChangeRulesChannelEvent; +import org.javacord.api.event.server.ServerChangeServerFeaturesEvent; import org.javacord.api.event.server.ServerChangeSplashEvent; import org.javacord.api.event.server.ServerChangeSystemChannelEvent; +import org.javacord.api.event.server.ServerChangeVanityUrlCodeEvent; import org.javacord.api.event.server.ServerChangeVerificationLevelEvent; +import org.javacord.core.entity.VanityUrlCodeImpl; import org.javacord.core.entity.server.ServerImpl; import org.javacord.core.event.server.ServerChangeAfkChannelEventImpl; import org.javacord.core.event.server.ServerChangeAfkTimeoutEventImpl; +import org.javacord.core.event.server.ServerChangeBoostCountEventImpl; +import org.javacord.core.event.server.ServerChangeBoostLevelEventImpl; import org.javacord.core.event.server.ServerChangeDefaultMessageNotificationLevelEventImpl; +import org.javacord.core.event.server.ServerChangeDescriptionEventImpl; +import org.javacord.core.event.server.ServerChangeDiscoverySplashEventImpl; import org.javacord.core.event.server.ServerChangeExplicitContentFilterLevelEventImpl; import org.javacord.core.event.server.ServerChangeIconEventImpl; +import org.javacord.core.event.server.ServerChangeModeratorsOnlyChannelEventImpl; import org.javacord.core.event.server.ServerChangeMultiFactorAuthenticationLevelEventImpl; import org.javacord.core.event.server.ServerChangeNameEventImpl; import org.javacord.core.event.server.ServerChangeOwnerEventImpl; +import org.javacord.core.event.server.ServerChangePreferredLocaleEventImpl; import org.javacord.core.event.server.ServerChangeRegionEventImpl; +import org.javacord.core.event.server.ServerChangeRulesChannelEventImpl; +import org.javacord.core.event.server.ServerChangeServerFeaturesEventImpl; import org.javacord.core.event.server.ServerChangeSplashEventImpl; import org.javacord.core.event.server.ServerChangeSystemChannelEventImpl; +import org.javacord.core.event.server.ServerChangeVanityUrlCodeEventImpl; import org.javacord.core.event.server.ServerChangeVerificationLevelEventImpl; import org.javacord.core.util.gateway.PacketHandler; +import org.javacord.core.util.logging.LoggerUtil; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Locale; import java.util.Objects; /** @@ -44,6 +71,11 @@ */ public class GuildUpdateHandler extends PacketHandler { + /** + * The logger of this class. + */ + private static final Logger logger = LoggerUtil.getLogger(GuildUpdateHandler.class); + /** * Creates a new instance of this class. * @@ -196,6 +228,123 @@ public void handle(JsonNode packet) { api.getEventDispatcher().dispatchServerChangeMultiFactorAuthenticationLevelEvent(server, server, event); } + + if (packet.has("rules_channel_id")) { + ServerTextChannel newRulesChannel = packet.get("rules_channel_id").isNull() + ? null + : server.getTextChannelById(packet.get("rules_channel_id").asLong()).orElse(null); + ServerTextChannel oldRulesChannel = server.getRulesChannel().orElse(null); + if (oldRulesChannel != newRulesChannel) { + server.setRulesChannelId(newRulesChannel == null ? -1 : newRulesChannel.getId()); + ServerChangeRulesChannelEvent event = + new ServerChangeRulesChannelEventImpl(server, newRulesChannel, oldRulesChannel); + + api.getEventDispatcher().dispatchServerChangeRulesChannelEvent(server, server, event); + } + } + + if (packet.has("public_updates_channel_id")) { + ServerTextChannel newModeratorsOnlyChannel = packet.get("public_updates_channel_id").isNull() + ? null + : server.getTextChannelById(packet.get("public_updates_channel_id").asLong()).orElse(null); + ServerTextChannel oldModeratorsOnlyChannel = server.getModeratorsOnlyChannel().orElse(null); + if (oldModeratorsOnlyChannel != newModeratorsOnlyChannel) { + server.setModeratorsOnlyChannelId( + newModeratorsOnlyChannel == null ? -1 : newModeratorsOnlyChannel.getId()); + ServerChangeModeratorsOnlyChannelEvent event = + new ServerChangeModeratorsOnlyChannelEventImpl( + server, newModeratorsOnlyChannel, oldModeratorsOnlyChannel); + + api.getEventDispatcher().dispatchServerChangeModeratorsOnlyChannelEvent(server, server, event); + } + } + + BoostLevel oldBoostLevel = server.getBoostLevel(); + BoostLevel newBoostLevel = BoostLevel.fromId(packet.get("premium_tier").asInt()); + if (oldBoostLevel != newBoostLevel) { + server.setBoostLevel(newBoostLevel); + ServerChangeBoostLevelEvent event = + new ServerChangeBoostLevelEventImpl(server, newBoostLevel, oldBoostLevel); + + api.getEventDispatcher().dispatchServerChangeBoostLevelEvent(server, server, event); + } + + Locale newPreferredLocale = + new Locale.Builder().setLanguageTag(packet.get("preferred_locale").asText()).build(); + Locale oldPreferredLocale = server.getPreferredLocale(); + if (!oldPreferredLocale.equals(newPreferredLocale)) { + server.setPreferredLocale(newPreferredLocale); + ServerChangePreferredLocaleEvent event = + new ServerChangePreferredLocaleEventImpl(server, newPreferredLocale, oldPreferredLocale); + + api.getEventDispatcher().dispatchServerChangePreferredLocaleEvent(server, server, event); + } + + int oldBoostCount = server.getBoostCount(); + int newBoostCount = packet.has("premium_subscription_count") + ? packet.get("premium_subscription_count").asInt() : 0; + if (oldBoostCount != newBoostCount) { + server.setServerBoostCount(newBoostCount); + ServerChangeBoostCountEvent event = + new ServerChangeBoostCountEventImpl(server, newBoostCount, oldBoostCount); + + api.getEventDispatcher().dispatchServerChangeBoostCountEvent(server, server, event); + } + + String oldDescription = server.getDescription().isPresent() ? server.getDescription().get() : null; + String newDescription = packet.hasNonNull("description") ? packet.get("description").asText() : null; + if (!Objects.deepEquals(oldDescription, newDescription)) { + server.setDescription(newDescription); + ServerChangeDescriptionEvent event = + new ServerChangeDescriptionEventImpl(server, newDescription, oldDescription); + + api.getEventDispatcher().dispatchServerChangeDescriptionEvent(server, server, event); + } + + String newDiscoverySplashHash = packet.get("discovery_splash").asText(null); + String oldDiscoverySplashHash = server.getDiscoverySplashHash(); + if (!Objects.deepEquals(oldDiscoverySplashHash, newDiscoverySplashHash)) { + server.setDiscoverySplashHash(newDiscoverySplashHash); + ServerChangeDiscoverySplashEvent event = new ServerChangeDiscoverySplashEventImpl( + server, newDiscoverySplashHash, oldDiscoverySplashHash); + + api.getEventDispatcher().dispatchServerChangeDiscoverySplashEvent(server, server, event); + } + + String oldVanityCode = server.getVanityUrlCode().map(VanityUrlCode::getCode).orElse(null); + String newVanityCode = packet.hasNonNull("vanity_url_code") ? packet.get("vanity_url_code").asText() : null; + if (!Objects.deepEquals(oldVanityCode, newVanityCode)) { + server.setVanityUrlCode(new VanityUrlCodeImpl(packet.get("vanity_url_code").asText())); + ServerChangeVanityUrlCodeEvent event = + new ServerChangeVanityUrlCodeEventImpl(server, newVanityCode, oldVanityCode); + + api.getEventDispatcher().dispatchServerChangeVanityUrlCodeEvent(server, server, event); + } + + Collection oldServerFeature = server.getFeatures(); + Collection newServerFeature = new ArrayList<>(); + if (packet.has("features")) { + packet.get("features").forEach(jsonNode -> { + try { + newServerFeature.add(ServerFeature.valueOf(jsonNode.asText())); + } catch (Exception ignored) { + logger.debug("Encountered server with unknown feature {}. Please update to the latest " + + "Javacord version or create an issue on the Javacord GitHub page if you are already " + + "on the latest version.", jsonNode.asText()); + } + }); + } + if (!(oldServerFeature.containsAll(newServerFeature) && newServerFeature.containsAll(oldServerFeature))) { + server.setServerFeatures(newServerFeature); + ServerChangeServerFeaturesEvent event = + new ServerChangeServerFeaturesEventImpl(server, newServerFeature, oldServerFeature); + + api.getEventDispatcher().dispatchServerChangeServerFeaturesEvent(server, server, event); + } + + if (packet.has("system_channel_flags")) { + server.setSystemChannelFlag(packet.get("system_channel_flags").asInt()); + } }); }