From c4d0930235e10617330d03ec926f78f47638118a Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Tue, 15 Oct 2024 21:39:39 +0200 Subject: [PATCH 01/31] Add soundboard sounds via GUILD_CREATE events --- .../net/dv8tion/jda/api/entities/Guild.java | 17 +++ .../jda/api/entities/SoundboardSound.java | 49 ++++++++ .../jda/api/utils/cache/CacheFlag.java | 6 + .../jda/internal/entities/EntityBuilder.java | 43 +++++++ .../jda/internal/entities/GuildImpl.java | 13 ++ .../entities/SoundboardSoundImpl.java | 117 ++++++++++++++++++ 6 files changed, 245 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java create mode 100644 src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index ab252daeed..14bb51c556 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -2052,6 +2052,23 @@ default List getStickersByName(@Nonnull String name, boolean ignor @Nonnull SnowflakeCacheView getStickerCache(); + @Nonnull + @Unmodifiable + default List getSoundboardSounds() + { + return getSoundboardCache().asList(); + } + + @Nonnull + @Unmodifiable + default List getSoundboardSoundsByName(@Nonnull String name, boolean ignoreCase) + { + return getSoundboardCache().getElementsByName(name, ignoreCase); + } + + @Nonnull + SnowflakeCacheView getSoundboardCache(); + /** * Retrieves an immutable list of Custom Emojis together with their respective creators. * diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java new file mode 100644 index 0000000000..d776732846 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities; + +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public interface SoundboardSound extends ISnowflake +{ + /** Template for {@link #getUrl()}.*/ + String SOUND_URL = "https://cdn.discordapp.com/soundboard-sounds/%s"; + + @Nonnull + default String getUrl() + { + return String.format(SOUND_URL, getId()); + } + + String getName(); + + double getVolume(); + + @Nullable + EmojiUnion getEmoji(); + + @Nullable + Guild getGuild(); + + boolean isAvailable(); + + @Nullable + User getUser(); +} diff --git a/src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java b/src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java index b9121f8da6..5e12e286ad 100644 --- a/src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java +++ b/src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java @@ -58,6 +58,12 @@ public enum CacheFlag *

Requires {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EXPRESSIONS GUILD_EXPRESSIONS} intent to be enabled. */ STICKER(GatewayIntent.GUILD_EXPRESSIONS), + /** + * Enables cache for {@link Guild#getSoundboardCache()} + * + *

Requires {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent to be enabled. + */ + SOUNDBOARD_SOUNDS(GatewayIntent.GUILD_EMOJIS_AND_STICKERS), /** * Enables cache for {@link Member#getOnlineStatus(net.dv8tion.jda.api.entities.ClientType) Member.getOnlineStatus(ClientType)} * diff --git a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java index 7fb94a3abe..785d7b7632 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java @@ -182,6 +182,23 @@ public static EmojiUnion createEmoji(DataObject emoji, String nameKey, String id return new CustomEmojiImpl(emoji.getString(nameKey, ""), id, emoji.getBoolean("animated")); } + public SoundboardSound createSoundboardSound(DataObject json) + { + String name = json.getString("name"); + long id = json.getLong("sound_id"); + double volume = json.getDouble("volume"); + EmojiUnion emoji; + if (!json.isNull("emoji_name") || !json.isNull("emoji_id")) + emoji = createEmoji(json, "emoji_name", "emoji_id"); + else + emoji = null; + Guild guild = getJDA().getGuildById(json.getLong("guild_id", 0)); + boolean available = json.getBoolean("available"); + User user = json.optObject("user").map(this::createUser).orElse(null); + + return new SoundboardSoundImpl(id, name, volume, emoji, guild, available, user); + } + private void createGuildEmojiPass(GuildImpl guildObj, DataArray array) { if (!getJDA().isCacheFlagSet(CacheFlag.EMOJI)) @@ -257,6 +274,30 @@ private void createGuildStickerPass(GuildImpl guildObj, DataArray array) } } + private void createGuildSoundboardSoundPass(GuildImpl guildObj, DataArray array) + { + if (!getJDA().isCacheFlagSet(CacheFlag.SOUNDBOARD_SOUNDS)) + return; + SnowflakeCacheViewImpl soundboardView = guildObj.getSoundboardSoundsView(); + try (UnlockHook hook = soundboardView.writeLock()) + { + TLongObjectMap soundboardMap = soundboardView.getMap(); + for (int i = 0; i < array.length(); i++) + { + DataObject object = array.getObject(i); + if (object.isNull("sound_id")) + { + LOG.error("Received GUILD_CREATE with a sound with a null ID. GuildId: {} JSON: {}", + guildObj.getId(), object); + continue; + } + + SoundboardSound sound = createSoundboardSound(object); + soundboardMap.put(sound.getIdLong(), sound); + } + } + } + public GuildImpl createGuild(long guildId, DataObject guildJson, TLongObjectMap members, int memberCount) { final GuildImpl guildObj = new GuildImpl(getJDA(), guildId); @@ -274,6 +315,7 @@ public GuildImpl createGuild(long guildId, DataObject guildJson, TLongObjectMap< final DataArray emojisArray = guildJson.getArray("emojis"); final DataArray voiceStateArray = guildJson.getArray("voice_states"); final Optional stickersArray = guildJson.optArray("stickers"); + final Optional soundboardSoundsArray = guildJson.optArray("soundboard_sounds"); final Optional featuresArray = guildJson.optArray("features"); final Optional presencesArray = guildJson.optArray("presences"); final long ownerId = guildJson.getUnsignedLong("owner_id", 0L); @@ -397,6 +439,7 @@ public GuildImpl createGuild(long guildId, DataObject guildJson, TLongObjectMap< createScheduledEventPass(guildObj, scheduledEventsArray); createGuildEmojiPass(guildObj, emojisArray); stickersArray.ifPresent(stickers -> createGuildStickerPass(guildObj, stickers)); + soundboardSoundsArray.ifPresent(stickers -> createGuildSoundboardSoundPass(guildObj, stickers)); guildJson.optArray("stage_instances") .map(arr -> arr.stream(DataArray::getObject)) .ifPresent(list -> list.forEach(it -> createStageInstance(guildObj, it))); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index 511ae41d7d..bac363eabc 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -108,6 +108,7 @@ public class GuildImpl implements Guild private final SortedSnowflakeCacheViewImpl roleCache = new SortedSnowflakeCacheViewImpl<>(Role.class, Role::getName, Comparator.reverseOrder()); private final SnowflakeCacheViewImpl emojicache = new SnowflakeCacheViewImpl<>(RichCustomEmoji.class, RichCustomEmoji::getName); private final SnowflakeCacheViewImpl stickerCache = new SnowflakeCacheViewImpl<>(GuildSticker.class, GuildSticker::getName); + private final SnowflakeCacheViewImpl soundboardCache = new SnowflakeCacheViewImpl<>(SoundboardSound.class, SoundboardSound::getName); private final MemberCacheViewImpl memberCache = new MemberCacheViewImpl(); private final CacheView.SimpleCacheView memberPresences; @@ -825,6 +826,13 @@ public SnowflakeCacheView getStickerCache() return stickerCache; } + @Nonnull + @Override + public SnowflakeCacheViewImpl getSoundboardCache() + { + return soundboardCache; + } + @Nonnull @Override public List getChannels(boolean includeHidden) @@ -2311,6 +2319,11 @@ public SnowflakeCacheViewImpl getStickersView() return stickerCache; } + public SnowflakeCacheViewImpl getSoundboardSoundsView() + { + return soundboardCache; + } + public MemberCacheViewImpl getMembersView() { return memberCache; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java new file mode 100644 index 0000000000..27d7016c8c --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java @@ -0,0 +1,117 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.internal.utils.EntityString; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class SoundboardSoundImpl implements SoundboardSound +{ + private final long id; + private final String name; + private final double volume; + private final EmojiUnion emoji; + private final Guild guild; + private final boolean available; + private final User user; + + public SoundboardSoundImpl(long id, String name, double volume, EmojiUnion emoji, Guild guild, boolean available, User user) + { + this.id = id; + this.name = name; + this.volume = volume; + this.emoji = emoji; + this.guild = guild; + this.available = available; + this.user = user; + } + + @Override + public long getIdLong() + { + return this.id; + } + + @Nonnull + @Override + public String getName() + { + return name; + } + + @Override + public double getVolume() + { + return volume; + } + + @Nullable + @Override + public EmojiUnion getEmoji() + { + return emoji; + } + + @Nullable + @Override + public Guild getGuild() + { + return guild; + } + + public boolean isAvailable() + { + return available; + } + + @Nullable + @Override + public User getUser() + { + return user; + } + + @Override + public int hashCode() + { + return Long.hashCode(id); + } + + @Override + public boolean equals(Object obj) + { + if (obj == this) + return true; + if (!(obj instanceof SoundboardSoundImpl)) + return false; + return ((SoundboardSoundImpl) obj).getIdLong() == this.id; + } + + @Override + public String toString() + { + return new EntityString(this) + .setName(name) + .toString(); + } +} From 2f457c01f0b098aed26bcac5dcba880b067301e5 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Tue, 15 Oct 2024 21:55:35 +0200 Subject: [PATCH 02/31] Add routes --- .../java/net/dv8tion/jda/api/requests/Route.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/requests/Route.java b/src/main/java/net/dv8tion/jda/api/requests/Route.java index b92d493cf2..00d36fd3bd 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/Route.java +++ b/src/main/java/net/dv8tion/jda/api/requests/Route.java @@ -178,6 +178,19 @@ public static class Stickers public static final Route LIST_PACKS = new Route(GET, "sticker-packs"); } + public static class SoundboardSounds + { + public static final Route SEND_SOUNDBOARD_SOUND = new Route(POST, "channels/{channel_id}/send-soundboard-sound"); + + public static final Route LIST_DEFAULT_SOUNDBOARD_SOUNDS = new Route(GET, "soundboard-default-sounds"); + + public static final Route LIST_GUILD_SOUNDBOARD_SOUNDS = new Route(GET, "guilds/{guild_id}/soundboard-sounds"); + public static final Route GET_GUILD_SOUNDBOARD_SOUNDS = new Route(GET, "guilds/{guild_id}/soundboard-sounds/{sound_id}"); + public static final Route CREATE_GUILD_SOUNDBOARD_SOUNDS = new Route(POST, "guilds/{guild_id}/soundboard-sounds"); + public static final Route MODIFY_GUILD_SOUNDBOARD_SOUNDS = new Route(PATCH, "guilds/{guild_id}/soundboard-sounds/{sound_id}"); + public static final Route DELETE_GUILD_SOUNDBOARD_SOUNDS = new Route(DELETE, "guilds/{guild_id}/soundboard-sounds/{sound_id}"); + } + public static class Webhooks { public static final Route GET_WEBHOOK = new Route(GET, "webhooks/{webhook_id}"); From d5f8d3b9ac921abc1c2c0cfde2689e25d5c4abf5 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Tue, 15 Oct 2024 21:56:07 +0200 Subject: [PATCH 03/31] Add JDA to SoundboardSound --- .../dv8tion/jda/api/entities/SoundboardSound.java | 4 ++++ .../dv8tion/jda/internal/entities/EntityBuilder.java | 2 +- .../jda/internal/entities/SoundboardSoundImpl.java | 12 +++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java index d776732846..d55ae6a3a9 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -16,6 +16,7 @@ package net.dv8tion.jda.api.entities; +import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import javax.annotation.Nonnull; @@ -26,6 +27,9 @@ public interface SoundboardSound extends ISnowflake /** Template for {@link #getUrl()}.*/ String SOUND_URL = "https://cdn.discordapp.com/soundboard-sounds/%s"; + @Nonnull + JDA getJDA(); + @Nonnull default String getUrl() { diff --git a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java index 785d7b7632..35bdb539d3 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java @@ -196,7 +196,7 @@ public SoundboardSound createSoundboardSound(DataObject json) boolean available = json.getBoolean("available"); User user = json.optObject("user").map(this::createUser).orElse(null); - return new SoundboardSoundImpl(id, name, volume, emoji, guild, available, user); + return new SoundboardSoundImpl(api, id, name, volume, emoji, guild, available, user); } private void createGuildEmojiPass(GuildImpl guildObj, DataArray array) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java index 27d7016c8c..6499e8bab8 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java @@ -16,6 +16,7 @@ package net.dv8tion.jda.internal.entities; +import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.SoundboardSound; import net.dv8tion.jda.api.entities.User; @@ -27,6 +28,7 @@ public class SoundboardSoundImpl implements SoundboardSound { + private final JDA api; private final long id; private final String name; private final double volume; @@ -35,8 +37,9 @@ public class SoundboardSoundImpl implements SoundboardSound private final boolean available; private final User user; - public SoundboardSoundImpl(long id, String name, double volume, EmojiUnion emoji, Guild guild, boolean available, User user) + public SoundboardSoundImpl(JDA api, long id, String name, double volume, EmojiUnion emoji, Guild guild, boolean available, User user) { + this.api = api; this.id = id; this.name = name; this.volume = volume; @@ -52,6 +55,13 @@ public long getIdLong() return this.id; } + @Nonnull + @Override + public JDA getJDA() + { + return api; + } + @Nonnull @Override public String getName() From 5f3f2c69f363b8cff649180b061bd61471260553 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Tue, 15 Oct 2024 21:57:40 +0200 Subject: [PATCH 04/31] Add SoundboardSound#sendTo --- .../jda/api/entities/SoundboardSound.java | 5 +++++ .../entities/SoundboardSoundImpl.java | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java index d55ae6a3a9..c3a7827996 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -17,7 +17,9 @@ package net.dv8tion.jda.api.entities; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.requests.RestAction; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -50,4 +52,7 @@ default String getUrl() @Nullable User getUser(); + + @Nonnull + RestAction sendTo(AudioChannel channel); } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java index 6499e8bab8..fa5d67a4c4 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java @@ -20,7 +20,12 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.SoundboardSound; import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.requests.Route; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.requests.RestActionImpl; import net.dv8tion.jda.internal.utils.EntityString; import javax.annotation.Nonnull; @@ -101,6 +106,20 @@ public User getUser() return user; } + @Nonnull + @Override + public RestAction sendTo(AudioChannel channel) + { + //TODO checks + DataObject data = DataObject.empty() + .put("sound_id", getId()); + + if (guild != null) + data.put("source_guild_id", guild.getId()); + + return new RestActionImpl<>(api, Route.SoundboardSounds.SEND_SOUNDBOARD_SOUND.compile(channel.getId()), data); + } + @Override public int hashCode() { From 8847924a3f5d7243f6bf2f48dd7e90a77634ac9f Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:15:02 +0200 Subject: [PATCH 05/31] Add Guild#createSoundboardSound --- .../net/dv8tion/jda/api/entities/Guild.java | 4 + .../SoundboardSoundCreateAction.java | 61 +++++++ .../jda/internal/entities/GuildImpl.java | 11 ++ .../SoundboardSoundCreateActionImpl.java | 162 ++++++++++++++++++ 4 files changed, 238 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java create mode 100644 src/main/java/net/dv8tion/jda/internal/requests/restaction/SoundboardSoundCreateActionImpl.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index 14bb51c556..4626d123d7 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -5028,6 +5028,10 @@ default AuditableRestAction createSticker(@Nonnull String name, @N @CheckReturnValue AuditableRestAction deleteSticker(@Nonnull StickerSnowflake id); + @Nonnull + @CheckReturnValue + SoundboardSoundCreateAction createSoundboardSound(@Nonnull String name, @Nonnull FileUpload file); + /** * Creates a new {@link ScheduledEvent}. * Events created with this method will be of {@link ScheduledEvent.Type#EXTERNAL Type.EXTERNAL}. diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java new file mode 100644 index 0000000000..b884626f6a --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java @@ -0,0 +1,61 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.requests.restaction; + +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.requests.RestAction; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.concurrent.TimeUnit; +import java.util.function.BooleanSupplier; + +/** + * Specialized {@link RestAction} used to create a {@link SoundboardSound} in a guild. + */ +public interface SoundboardSoundCreateAction extends AuditableRestAction +{ + @Nonnull + @Override + @CheckReturnValue + SoundboardSoundCreateAction timeout(long timeout, @Nonnull TimeUnit unit); + + @Nonnull + @Override + @CheckReturnValue + SoundboardSoundCreateAction deadline(long timestamp); + + @Nonnull + @Override + @CheckReturnValue + SoundboardSoundCreateAction setCheck(@Nullable BooleanSupplier checks); + + @Nonnull + @Override + @CheckReturnValue + SoundboardSoundCreateAction addCheck(@Nonnull BooleanSupplier checks); + + @Nonnull + @CheckReturnValue + SoundboardSoundCreateAction setVolume(double volume); + + @Nonnull + @CheckReturnValue + SoundboardSoundCreateAction setEmoji(@Nonnull Emoji emoji); +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index bac363eabc..bb5b051101 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -1968,6 +1968,17 @@ public AuditableRestAction deleteSticker(@Nonnull StickerSnowflake id) return new AuditableRestActionImpl<>(api, route); } + @Nonnull + @Override + public SoundboardSoundCreateAction createSoundboardSound(@Nonnull String name, @Nonnull FileUpload file) + { + checkPermission(Permission.CREATE_GUILD_EXPRESSIONS); + Checks.notNull(name, "Name"); + Checks.notNull(file, "File"); + Route.CompiledRoute route = Route.SoundboardSounds.CREATE_GUILD_SOUNDBOARD_SOUNDS.compile(getId()); + return new SoundboardSoundCreateActionImpl(getJDA(), route, name, file); + } + @Nonnull @Override public ChannelOrderAction modifyCategoryPositions() diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/SoundboardSoundCreateActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/SoundboardSoundCreateActionImpl.java new file mode 100644 index 0000000000..5959ca188d --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/SoundboardSoundCreateActionImpl.java @@ -0,0 +1,162 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.requests.restaction; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.emoji.CustomEmoji; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.entities.emoji.UnicodeEmoji; +import net.dv8tion.jda.api.requests.Request; +import net.dv8tion.jda.api.requests.Response; +import net.dv8tion.jda.api.requests.Route; +import net.dv8tion.jda.api.requests.restaction.SoundboardSoundCreateAction; +import net.dv8tion.jda.api.utils.FileUpload; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.utils.Checks; +import net.dv8tion.jda.internal.utils.IOUtil; +import okhttp3.RequestBody; + +import javax.annotation.Nonnull; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Locale; +import java.util.concurrent.TimeUnit; +import java.util.function.BooleanSupplier; + +public class SoundboardSoundCreateActionImpl extends AuditableRestActionImpl implements SoundboardSoundCreateAction +{ + private final String name; + private final FileUpload file; + private double volume = 1; + private Emoji emoji; + + public SoundboardSoundCreateActionImpl(JDA api, Route.CompiledRoute route, String name, FileUpload file) + { + super(api, route); + this.name = name; + this.file = file; + } + + @Nonnull + @Override + public SoundboardSoundCreateAction timeout(long timeout, @Nonnull TimeUnit unit) + { + return (SoundboardSoundCreateAction) super.timeout(timeout, unit); + } + + @Nonnull + @Override + public SoundboardSoundCreateAction addCheck(@Nonnull BooleanSupplier checks) + { + return (SoundboardSoundCreateAction) super.addCheck(checks); + } + + @Nonnull + @Override + public SoundboardSoundCreateAction setCheck(BooleanSupplier checks) + { + return (SoundboardSoundCreateAction) super.setCheck(checks); + } + + @Nonnull + @Override + public SoundboardSoundCreateAction deadline(long timestamp) + { + return (SoundboardSoundCreateAction) super.deadline(timestamp); + } + + @Nonnull + @Override + public SoundboardSoundCreateAction setVolume(double volume) + { + Checks.check(volume >= 0 && volume <= 1, "Volume must be between 0 and 1"); + this.volume = volume; + return this; + } + + @Nonnull + @Override + public SoundboardSoundCreateAction setEmoji(@Nonnull Emoji emoji) + { + Checks.notNull(emoji, "Emoji"); + this.emoji = emoji; + return this; + } + + @Override + protected RequestBody finalizeData() + { + try + { + final DataObject json = DataObject.empty() + .put("name", name) + .put("sound", "data:" + getMime() + ";base64," + getBase64Sound()) + .put("volume", volume); + + if (emoji instanceof UnicodeEmoji) { + json.put("emoji_name", emoji.getName()); + } else if (emoji instanceof CustomEmoji) { + json.put("emoji_id", ((CustomEmoji) emoji).getId()); + } + + return getRequestBody(json); + } + catch (IOException e) + { + throw new UncheckedIOException("Unable to get request body when creating a guild soundboard sound", e); + } + } + + @Nonnull + private String getBase64Sound() throws IOException + { + final byte[] data = IOUtil.readFully(file.getData()); + final byte[] b64 = Base64.getEncoder().encode(data); + return new String(b64, StandardCharsets.UTF_8); + } + + @Nonnull + private String getMime() + { + int index = file.getName().lastIndexOf('.'); + Checks.check(index > -1, "Filename for soundboard sound is missing file extension. Provided: '" + file.getName() + "'. Must be MP3 or OGG."); + + String extension = file.getName().substring(index + 1).toLowerCase(Locale.ROOT); + String mime; + switch (extension) + { + case "mp3": + mime = "audio/mpeg"; + break; + case "ogg": + mime = "audio/ogg"; + break; + default: + throw new IllegalArgumentException("Unsupported file extension: '." + extension + "', must be MP3 or OGG."); + } + return mime; + } + + @Override + protected void handleSuccess(Response response, Request request) + { + request.onSuccess(api.getEntityBuilder().createSoundboardSound(response.getObject())); + } +} From 2cc2645484f572c43d1ca6593f7fe975e0df1200 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:23:12 +0200 Subject: [PATCH 06/31] Add JDA#retrieveDefaultSoundboardSounds --- src/main/java/net/dv8tion/jda/api/JDA.java | 4 ++++ .../java/net/dv8tion/jda/internal/JDAImpl.java | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/JDA.java b/src/main/java/net/dv8tion/jda/api/JDA.java index 7f50e3b45c..dce013a7f3 100644 --- a/src/main/java/net/dv8tion/jda/api/JDA.java +++ b/src/main/java/net/dv8tion/jda/api/JDA.java @@ -1845,6 +1845,10 @@ default RestAction retrieveApplicationEmojiById(long emojiId) @CheckReturnValue RestAction<@Unmodifiable List> retrieveNitroStickerPacks(); + @Nonnull + @CheckReturnValue + RestAction<@Unmodifiable List> retrieveDefaultSoundboardSounds(); + /** * The EventManager used by this JDA instance. * diff --git a/src/main/java/net/dv8tion/jda/internal/JDAImpl.java b/src/main/java/net/dv8tion/jda/internal/JDAImpl.java index 9c1be36130..6f3ccce671 100644 --- a/src/main/java/net/dv8tion/jda/internal/JDAImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/JDAImpl.java @@ -84,6 +84,7 @@ import net.dv8tion.jda.internal.utils.config.ThreadingConfig; import okhttp3.OkHttpClient; import okhttp3.RequestBody; +import org.jetbrains.annotations.Unmodifiable; import org.slf4j.Logger; import org.slf4j.MDC; @@ -771,6 +772,21 @@ public RestAction> retrieveNitroStickerPacks() }); } + @Nonnull + @Override + public RestAction<@Unmodifiable List> retrieveDefaultSoundboardSounds() + { + final Route.CompiledRoute route = Route.SoundboardSounds.LIST_DEFAULT_SOUNDBOARD_SOUNDS.compile(); + return new RestActionImpl<>(this, route, (response, request) -> + { + final DataArray array = response.getArray(); + List sounds = new ArrayList<>(array.length()); + for (int i = 0; i < array.length(); i++) + sounds.add(entityBuilder.createSoundboardSound(array.getObject(i))); + return Collections.unmodifiableList(sounds); + }); + } + @Nonnull @Override public SnowflakeCacheView getScheduledEventCache() From 3ad6f8904a3bc21ec9fdea09ca6120be2fce3b75 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:40:11 +0200 Subject: [PATCH 07/31] Fix tests --- .../java/net/dv8tion/jda/api/entities/SoundboardSound.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java index c3a7827996..7192ff4256 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -21,6 +21,7 @@ import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import net.dv8tion.jda.api.requests.RestAction; +import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -38,6 +39,7 @@ default String getUrl() return String.format(SOUND_URL, getId()); } + @Nonnull String getName(); double getVolume(); @@ -54,5 +56,6 @@ default String getUrl() User getUser(); @Nonnull + @CheckReturnValue RestAction sendTo(AudioChannel channel); } From 76ad02dc6fd48aab76f07ab0acf80e7b22374d44 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:42:16 +0200 Subject: [PATCH 08/31] Add SoundboardSound#delete --- .../jda/api/entities/SoundboardSound.java | 4 +++ .../entities/SoundboardSoundImpl.java | 27 +++++++++++++++ .../jda/internal/utils/PermissionUtil.java | 34 ++++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java index 7192ff4256..cf4d67af5c 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -58,4 +58,8 @@ default String getUrl() @Nonnull @CheckReturnValue RestAction sendTo(AudioChannel channel); + + @Nonnull + @CheckReturnValue + RestAction delete(); } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java index fa5d67a4c4..b78f87b8ee 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java @@ -17,19 +17,26 @@ package net.dv8tion.jda.internal.entities; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.SoundboardSound; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.Route; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.requests.RestActionImpl; +import net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl; +import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.EntityString; +import net.dv8tion.jda.internal.utils.PermissionUtil; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Objects; public class SoundboardSoundImpl implements SoundboardSound { @@ -120,6 +127,26 @@ public RestAction sendTo(AudioChannel channel) return new RestActionImpl<>(api, Route.SoundboardSounds.SEND_SOUNDBOARD_SOUND.compile(channel.getId()), data); } + @Nonnull + @Override + public RestAction delete() + { + Checks.check(getGuild() != null, "Cannot delete default soundboard sounds"); + checkEditPermissions(); + + final Route.CompiledRoute route = Route.SoundboardSounds.DELETE_GUILD_SOUNDBOARD_SOUNDS.compile(guild.getId(), getId()); + return new AuditableRestActionImpl<>(api, route); + } + + private void checkEditPermissions() + { + final Member selfMember = guild.getSelfMember(); + if (Objects.equals(getUser(), selfMember.getUser())) + PermissionUtil.requireAnyPermission(selfMember, Permission.CREATE_GUILD_EXPRESSIONS, Permission.MANAGE_GUILD_EXPRESSIONS); + else if (!selfMember.hasPermission(Permission.MANAGE_GUILD_EXPRESSIONS)) + throw new InsufficientPermissionException(guild, Permission.MANAGE_GUILD_EXPRESSIONS); + } + @Override public int hashCode() { diff --git a/src/main/java/net/dv8tion/jda/internal/utils/PermissionUtil.java b/src/main/java/net/dv8tion/jda/internal/utils/PermissionUtil.java index 67fcf28e16..913d21a8d8 100644 --- a/src/main/java/net/dv8tion/jda/internal/utils/PermissionUtil.java +++ b/src/main/java/net/dv8tion/jda/internal/utils/PermissionUtil.java @@ -23,12 +23,14 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.entities.emoji.RichCustomEmoji; +import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import org.apache.commons.collections4.CollectionUtils; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; +import java.util.stream.Stream; public class PermissionUtil { @@ -37,7 +39,7 @@ public class PermissionUtil Arrays.stream(Permission.values()) .filter(Permission::isChannel) .collect(Collectors.toList())); - + /** * Checks if one given Member can interact with a 2nd given Member - in a permission sense (kick/ban/modify perms). * This only checks the Role-Position and does not check the actual permission (kick/ban/manage_role/...) @@ -252,6 +254,36 @@ public static boolean checkPermission(Member member, Permission... permissions) || isApplied(effectivePerms, Permission.getRaw(permissions)); } + /** + * Checks if the member has any of the specified permissions. Also checks for owners and administrators. + * + * @param member + * The member whose permissions are being checked + * @param permissions + * The permissions being checked for + * + * @throws IllegalArgumentException + * If any of the provided parameters are null, or no permissions were given + * @throws InsufficientPermissionException + * If the member has none of the specified permissions + */ + public static void requireAnyPermission(Member member, Permission... permissions) + { + Checks.notNull(member, "Member"); + Checks.notEmpty(permissions, "Permissions"); + + for (Permission permission : permissions) + { + if (member.hasPermission(permission)) + return; + } + + String reason = Stream.of(permissions) + .map(Permission::name) + .collect(Collectors.joining(" or ")); + throw new InsufficientPermissionException(member.getGuild(), permissions[0], "You need the " + reason + " permission to perform this action!"); + } + /** * Checks to see if the {@link net.dv8tion.jda.api.entities.Member Member} has the specified {@link net.dv8tion.jda.api.Permission Permissions} * in the specified {@link IPermissionContainer GuildChannel}. This method properly deals with From 2e152535fc698119db000507c4b11657cefd92ce Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:49:51 +0200 Subject: [PATCH 09/31] Handle create/update/delete --- .../GuildSoundboardSoundsCreateHandler.java | 59 +++++++++++++++++++ .../GuildSoundboardSoundsDeleteHandler.java | 58 ++++++++++++++++++ .../GuildSoundboardSoundsUpdateHandler.java | 59 +++++++++++++++++++ .../internal/requests/WebSocketClient.java | 3 + 4 files changed, 179 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java create mode 100644 src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java create mode 100644 src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java new file mode 100644 index 0000000000..f39a619f74 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.utils.cache.CacheFlag; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.GuildImpl; +import net.dv8tion.jda.internal.utils.UnlockHook; +import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; + +public class GuildSoundboardSoundsCreateHandler extends SocketHandler +{ + public GuildSoundboardSoundsCreateHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + if (!getJDA().isCacheFlagSet(CacheFlag.SOUNDBOARD_SOUNDS)) + return null; + final long guildId = content.getLong("guild_id"); + if (getJDA().getGuildSetupController().isLocked(guildId)) + return guildId; + + GuildImpl guild = (GuildImpl) getJDA().getGuildById(guildId); + if (guild == null) + { + getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + return null; + } + + final SoundboardSound soundboardSound = api.getEntityBuilder().createSoundboardSound(content); + final SnowflakeCacheViewImpl soundboardSoundsView = guild.getSoundboardSoundsView(); + try (UnlockHook unlockHook = soundboardSoundsView.writeLock()) + { + soundboardSoundsView.getMap().put(soundboardSound.getIdLong(), soundboardSound); + } + + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java new file mode 100644 index 0000000000..a402354a81 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.utils.cache.CacheFlag; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.GuildImpl; +import net.dv8tion.jda.internal.utils.UnlockHook; +import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; + +public class GuildSoundboardSoundsDeleteHandler extends SocketHandler +{ + public GuildSoundboardSoundsDeleteHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + if (!getJDA().isCacheFlagSet(CacheFlag.SOUNDBOARD_SOUNDS)) + return null; + final long guildId = content.getLong("guild_id"); + if (getJDA().getGuildSetupController().isLocked(guildId)) + return guildId; + + GuildImpl guild = (GuildImpl) getJDA().getGuildById(guildId); + if (guild == null) + { + getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + return null; + } + + final SnowflakeCacheViewImpl soundboardSoundsView = guild.getSoundboardSoundsView(); + try (UnlockHook unlockHook = soundboardSoundsView.writeLock()) + { + soundboardSoundsView.getMap().remove(content.getLong("sound_id")); + } + + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java new file mode 100644 index 0000000000..d952f0f570 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.utils.cache.CacheFlag; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.GuildImpl; +import net.dv8tion.jda.internal.utils.UnlockHook; +import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; + +public class GuildSoundboardSoundsUpdateHandler extends SocketHandler +{ + public GuildSoundboardSoundsUpdateHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + if (!getJDA().isCacheFlagSet(CacheFlag.SOUNDBOARD_SOUNDS)) + return null; + final long guildId = content.getLong("guild_id"); + if (getJDA().getGuildSetupController().isLocked(guildId)) + return guildId; + + GuildImpl guild = (GuildImpl) getJDA().getGuildById(guildId); + if (guild == null) + { + getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + return null; + } + + final SoundboardSound soundboardSound = api.getEntityBuilder().createSoundboardSound(content); + final SnowflakeCacheViewImpl soundboardSoundsView = guild.getSoundboardSoundsView(); + try (UnlockHook unlockHook = soundboardSoundsView.writeLock()) + { + soundboardSoundsView.getMap().put(soundboardSound.getIdLong(), soundboardSound); + } + + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java index 401bcbf683..9f2e1d7725 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java @@ -1397,6 +1397,9 @@ protected void setupHandlers() handlers.put("GUILD_ROLE_UPDATE", new GuildRoleUpdateHandler(api)); handlers.put("GUILD_SYNC", new GuildSyncHandler(api)); handlers.put("GUILD_STICKERS_UPDATE", new GuildStickersUpdateHandler(api)); + handlers.put("GUILD_SOUNDBOARD_SOUND_CREATE", new GuildSoundboardSoundsCreateHandler(api)); + handlers.put("GUILD_SOUNDBOARD_SOUND_UPDATE", new GuildSoundboardSoundsUpdateHandler(api)); + handlers.put("GUILD_SOUNDBOARD_SOUND_DELETE", new GuildSoundboardSoundsDeleteHandler(api)); handlers.put("GUILD_UPDATE", new GuildUpdateHandler(api)); handlers.put("INTERACTION_CREATE", new InteractionCreateHandler(api)); handlers.put("INVITE_CREATE", new InviteCreateHandler(api)); From 1f653c57173c844becc79212cb9417390d96ce87 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:04:11 +0200 Subject: [PATCH 10/31] Add generic/create/delete events --- .../GenericSoundboardSoundEvent.java | 58 +++++++++++++++++++ .../SoundboardSoundCreateEvent.java | 30 ++++++++++ .../SoundboardSoundDeleteEvent.java | 30 ++++++++++ .../api/events/soundboard/package-info.java | 28 +++++++++ .../jda/api/hooks/ListenerAdapter.java | 8 +++ .../GuildSoundboardSoundsCreateHandler.java | 3 + .../GuildSoundboardSoundsDeleteHandler.java | 7 ++- 7 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/GenericSoundboardSoundEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundCreateEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundDeleteEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/package-info.java diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/GenericSoundboardSoundEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/GenericSoundboardSoundEvent.java new file mode 100644 index 0000000000..a065e6b594 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/GenericSoundboardSoundEvent.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.soundboard; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.events.Event; + +import javax.annotation.Nonnull; + +public abstract class GenericSoundboardSoundEvent extends Event +{ + private final SoundboardSound soundboardSound; + + public GenericSoundboardSoundEvent(@Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound) + { + super(api, responseNumber); + this.soundboardSound = soundboardSound; + } + + /** + * The {@link Guild} where the soundboard sound came from + * + * @return The origin Guild + */ + @Nonnull + @SuppressWarnings("DataFlowIssue") // This event is guild-only + public Guild getGuild() + { + return soundboardSound.getGuild(); + } + + /** + * The affected {@link SoundboardSound} for this event + * + * @return The soundboard sound + */ + @Nonnull + public SoundboardSound getSoundboardSound() + { + return soundboardSound; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundCreateEvent.java new file mode 100644 index 0000000000..073b1f1f11 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundCreateEvent.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.soundboard; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.SoundboardSound; + +import javax.annotation.Nonnull; + +public class SoundboardSoundCreateEvent extends GenericSoundboardSoundEvent +{ + public SoundboardSoundCreateEvent(@Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound) + { + super(api, responseNumber, soundboardSound); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundDeleteEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundDeleteEvent.java new file mode 100644 index 0000000000..9828e5b70c --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundDeleteEvent.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.soundboard; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.SoundboardSound; + +import javax.annotation.Nonnull; + +public class SoundboardSoundDeleteEvent extends GenericSoundboardSoundEvent +{ + public SoundboardSoundDeleteEvent(@Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound) + { + super(api, responseNumber, soundboardSound); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/package-info.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/package-info.java new file mode 100644 index 0000000000..0cf5c8c3ea --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/package-info.java @@ -0,0 +1,28 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Events that track {@link net.dv8tion.jda.api.events.soundboard.SoundboardSoundCreateEvent created soundboard sounds} + * and {@link net.dv8tion.jda.api.events.soundboard.SoundboardSoundDeleteEvent deleted soundboard sounds}. + * + *

Requirements
+ * + *

These events require the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires + * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. + * + *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + */ +package net.dv8tion.jda.api.events.soundboard; diff --git a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java index 81e5ae6a49..f7a42d4ba1 100644 --- a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java +++ b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java @@ -69,6 +69,9 @@ import net.dv8tion.jda.api.events.role.update.*; import net.dv8tion.jda.api.events.self.*; import net.dv8tion.jda.api.events.session.*; +import net.dv8tion.jda.api.events.soundboard.GenericSoundboardSoundEvent; +import net.dv8tion.jda.api.events.soundboard.SoundboardSoundCreateEvent; +import net.dv8tion.jda.api.events.soundboard.SoundboardSoundDeleteEvent; import net.dv8tion.jda.api.events.stage.GenericStageInstanceEvent; import net.dv8tion.jda.api.events.stage.StageInstanceCreateEvent; import net.dv8tion.jda.api.events.stage.StageInstanceDeleteEvent; @@ -369,6 +372,10 @@ public void onGuildStickerUpdateTags(@Nonnull GuildStickerUpdateTagsEvent event) public void onGuildStickerUpdateDescription(@Nonnull GuildStickerUpdateDescriptionEvent event) {} public void onGuildStickerUpdateAvailable(@Nonnull GuildStickerUpdateAvailableEvent event) {} + // Soundboard sound events + public void onSoundboardSoundCreate(@Nonnull SoundboardSoundCreateEvent event) {} + public void onSoundboardSoundDelete(@Nonnull SoundboardSoundDeleteEvent event) {} + // Entitlement events public void onEntitlementCreate(@Nonnull EntitlementCreateEvent event) {} public void onEntitlementUpdate(@Nonnull EntitlementUpdateEvent event) {} @@ -411,6 +418,7 @@ public void onGenericEmoji(@Nonnull GenericEmojiEvent event) {} public void onGenericEmojiUpdate(@Nonnull GenericEmojiUpdateEvent event) {} public void onGenericGuildSticker(@Nonnull GenericGuildStickerEvent event) {} public void onGenericGuildStickerUpdate(@Nonnull GenericGuildStickerUpdateEvent event) {} + public void onGenericSoundboardSound(@Nonnull GenericSoundboardSoundEvent event) {} public void onGenericEntitlement(@Nonnull GenericEntitlementEvent event) {} public void onGenericPermissionOverride(@Nonnull GenericPermissionOverrideEvent event) {} public void onGenericScheduledEventUpdate(@Nonnull GenericScheduledEventUpdateEvent event) {} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java index f39a619f74..9f0e2261dd 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.internal.handle; import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.events.soundboard.SoundboardSoundCreateEvent; import net.dv8tion.jda.api.utils.cache.CacheFlag; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; @@ -54,6 +55,8 @@ protected Long handleInternally(DataObject content) soundboardSoundsView.getMap().put(soundboardSound.getIdLong(), soundboardSound); } + api.handleEvent(new SoundboardSoundCreateEvent(api, responseNumber, soundboardSound)); + return null; } } diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java index a402354a81..bb6a1d2819 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.internal.handle; import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.events.soundboard.SoundboardSoundDeleteEvent; import net.dv8tion.jda.api.utils.cache.CacheFlag; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; @@ -48,11 +49,15 @@ protected Long handleInternally(DataObject content) } final SnowflakeCacheViewImpl soundboardSoundsView = guild.getSoundboardSoundsView(); + final SoundboardSound removedSound; try (UnlockHook unlockHook = soundboardSoundsView.writeLock()) { - soundboardSoundsView.getMap().remove(content.getLong("sound_id")); + removedSound = soundboardSoundsView.getMap().remove(content.getLong("sound_id")); } + if (removedSound != null) + api.handleEvent(new SoundboardSoundDeleteEvent(api, responseNumber, removedSound)); + return null; } } From 8f506cd91b78fecb5c1b60e8a5e35966a260169b Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:35:54 +0200 Subject: [PATCH 11/31] Cache and replay soundboard sound updates if not created yet --- .../net/dv8tion/jda/internal/handle/EventCache.java | 2 +- .../handle/GuildSoundboardSoundsUpdateHandler.java | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/internal/handle/EventCache.java b/src/main/java/net/dv8tion/jda/internal/handle/EventCache.java index 45e8cd5847..3abe6d8007 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/EventCache.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/EventCache.java @@ -129,7 +129,7 @@ public synchronized void clear(Type type, long id) public enum Type { - USER, MEMBER, GUILD, CHANNEL, ROLE, RELATIONSHIP, CALL, SCHEDULED_EVENT + USER, MEMBER, GUILD, CHANNEL, ROLE, SOUNDBOARD_SOUND, RELATIONSHIP, CALL, SCHEDULED_EVENT } private class CacheNode diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java index d952f0f570..165815f635 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java @@ -47,8 +47,17 @@ protected Long handleInternally(DataObject content) return null; } + SnowflakeCacheViewImpl soundboardSoundsView = guild.getSoundboardSoundsView(); + long soundId = content.getLong("sound_id"); + final SoundboardSound oldSoundboardSound = soundboardSoundsView.get(soundId); + if (oldSoundboardSound == null) + { + getJDA().getEventCache().cache(EventCache.Type.SOUNDBOARD_SOUND, soundId, responseNumber, allContent, this::handle); + EventCache.LOG.debug("Received a Guild Soundboard Sound Update for SoundboardSound that is not yet cached: {}", content); + return null; + } + final SoundboardSound soundboardSound = api.getEntityBuilder().createSoundboardSound(content); - final SnowflakeCacheViewImpl soundboardSoundsView = guild.getSoundboardSoundsView(); try (UnlockHook unlockHook = soundboardSoundsView.writeLock()) { soundboardSoundsView.getMap().put(soundboardSound.getIdLong(), soundboardSound); From 4dbab04a4fb156f3170519fb1a4e5721e821361c Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:36:50 +0200 Subject: [PATCH 12/31] Add update events --- .../GenericSoundboardSoundUpdateEvent.java | 80 ++++++++++++++++++ .../SoundboardSoundUpdateEmojiEvent.java | 84 +++++++++++++++++++ .../SoundboardSoundUpdateNameEvent.java | 84 +++++++++++++++++++ .../SoundboardSoundUpdateVolumeEvent.java | 82 ++++++++++++++++++ .../soundboard/update/package-info.java | 27 ++++++ .../jda/api/hooks/ListenerAdapter.java | 10 +++ .../GuildSoundboardSoundsUpdateHandler.java | 14 ++++ 7 files changed, 381 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/update/GenericSoundboardSoundUpdateEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateEmojiEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateNameEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateVolumeEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/GenericSoundboardSoundUpdateEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/GenericSoundboardSoundUpdateEvent.java new file mode 100644 index 0000000000..6b5cb967bd --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/GenericSoundboardSoundUpdateEvent.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.soundboard.update; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.events.UpdateEvent; +import net.dv8tion.jda.api.events.soundboard.GenericSoundboardSoundEvent; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Indicates that a {@link SoundboardSound soundboard sound} was updated. + * + *

Requirements
+ * + *

These events require the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires + * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. + * + *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + */ +public abstract class GenericSoundboardSoundUpdateEvent extends GenericSoundboardSoundEvent implements UpdateEvent +{ + protected final T previous; + protected final T next; + protected final String identifier; + + public GenericSoundboardSoundUpdateEvent( + @Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound, + @Nullable T previous, @Nullable T next, @Nonnull String identifier) + { + super(api, responseNumber, soundboardSound); + this.previous = previous; + this.next = next; + this.identifier = identifier; + } + + @Nonnull + @Override + public SoundboardSound getEntity() + { + return getSoundboardSound(); + } + + @Nonnull + @Override + public String getPropertyIdentifier() + { + return identifier; + } + + @Nullable + @Override + public T getOldValue() + { + return previous; + } + + @Nullable + @Override + public T getNewValue() + { + return next; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateEmojiEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateEmojiEvent.java new file mode 100644 index 0000000000..613776909a --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateEmojiEvent.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.soundboard.update; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Indicates that the emoji of a {@link SoundboardSound soundboard sound} changed. + * + *

Can be used to retrieve the old emoji + * + *

Requirements
+ * + *

This event requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires + * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. + * + *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + * + *

Identifier: {@value IDENTIFIER} + */ +public class SoundboardSoundUpdateEmojiEvent extends GenericSoundboardSoundUpdateEvent +{ + public static final String IDENTIFIER = "emoji"; + + public SoundboardSoundUpdateEmojiEvent(@Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound, EmojiUnion oldEmoji) + { + super(api, responseNumber, soundboardSound, oldEmoji, soundboardSound.getEmoji(), IDENTIFIER); + } + + /** + * The old emoji + * + * @return The old emoji + */ + @Nullable + public EmojiUnion getOldEmoji() + { + return getOldValue(); + } + + /** + * The new emoji + * + * @return The new emoji + */ + @Nullable + public EmojiUnion getNewEmoji() + { + return getNewValue(); + } + + @Nullable + @Override + public EmojiUnion getOldValue() + { + return super.getOldValue(); + } + + @Nullable + @Override + public EmojiUnion getNewValue() + { + return super.getNewValue(); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateNameEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateNameEvent.java new file mode 100644 index 0000000000..53e7fe5dcb --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateNameEvent.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.soundboard.update; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.SoundboardSound; + +import javax.annotation.Nonnull; + +/** + * Indicates that the name of a {@link SoundboardSound soundboard sound} changed. + * + *

Can be used to retrieve the old name + * + *

Requirements
+ * + *

This event requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires + * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. + * + *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + * + *

Identifier: {@value IDENTIFIER} + */ +public class SoundboardSoundUpdateNameEvent extends GenericSoundboardSoundUpdateEvent +{ + public static final String IDENTIFIER = "name"; + + public SoundboardSoundUpdateNameEvent(@Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound, @Nonnull String oldName) + { + super(api, responseNumber, soundboardSound, oldName, soundboardSound.getName(), IDENTIFIER); + } + + /** + * The old name + * + * @return The old name + */ + @Nonnull + public String getOldName() + { + return getOldValue(); + } + + /** + * The new name + * + * @return The new name + */ + @Nonnull + public String getNewName() + { + return getNewValue(); + } + + @Nonnull + @Override + @SuppressWarnings("DataFlowIssue") + public String getOldValue() + { + return super.getOldValue(); + } + + @Nonnull + @Override + @SuppressWarnings("DataFlowIssue") + public String getNewValue() + { + return super.getNewValue(); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateVolumeEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateVolumeEvent.java new file mode 100644 index 0000000000..8e8eb18742 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateVolumeEvent.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.soundboard.update; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.SoundboardSound; + +import javax.annotation.Nonnull; + +/** + * Indicates that the volume of a {@link SoundboardSound soundboard sound} changed. + * + *

Can be used to retrieve the old volume + * + *

Requirements
+ * + *

This event requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires + * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. + * + *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + * + *

Identifier: {@value IDENTIFIER} + */ +public class SoundboardSoundUpdateVolumeEvent extends GenericSoundboardSoundUpdateEvent +{ + public static final String IDENTIFIER = "volume"; + + public SoundboardSoundUpdateVolumeEvent(@Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound, double oldVolume) + { + super(api, responseNumber, soundboardSound, oldVolume, soundboardSound.getVolume(), IDENTIFIER); + } + + /** + * The old volume + * + * @return The old volume + */ + public double getOldVolume() + { + return getOldValue(); + } + + /** + * The new volume + * + * @return The new volume + */ + public double getNewVolume() + { + return getNewValue(); + } + + @Nonnull + @Override + @SuppressWarnings("DataFlowIssue") + public Double getOldValue() + { + return super.getOldValue(); + } + + @Nonnull + @Override + @SuppressWarnings("DataFlowIssue") + public Double getNewValue() + { + return super.getNewValue(); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java new file mode 100644 index 0000000000..9da41434aa --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Events that track updates for existing {@link net.dv8tion.jda.api.entities.SoundboardSound Soundboard sounds} + * + *

Requirements
+ * + *

These events require the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires + * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. + * + *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + */ +package net.dv8tion.jda.api.events.soundboard.update; diff --git a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java index f7a42d4ba1..862d5d8566 100644 --- a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java +++ b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java @@ -72,6 +72,10 @@ import net.dv8tion.jda.api.events.soundboard.GenericSoundboardSoundEvent; import net.dv8tion.jda.api.events.soundboard.SoundboardSoundCreateEvent; import net.dv8tion.jda.api.events.soundboard.SoundboardSoundDeleteEvent; +import net.dv8tion.jda.api.events.soundboard.update.GenericSoundboardSoundUpdateEvent; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateEmojiEvent; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateNameEvent; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateVolumeEvent; import net.dv8tion.jda.api.events.stage.GenericStageInstanceEvent; import net.dv8tion.jda.api.events.stage.StageInstanceCreateEvent; import net.dv8tion.jda.api.events.stage.StageInstanceDeleteEvent; @@ -376,6 +380,11 @@ public void onGuildStickerUpdateAvailable(@Nonnull GuildStickerUpdateAvailableEv public void onSoundboardSoundCreate(@Nonnull SoundboardSoundCreateEvent event) {} public void onSoundboardSoundDelete(@Nonnull SoundboardSoundDeleteEvent event) {} + // Soundboard sound update events + public void onSoundboardSoundUpdateName(@Nonnull SoundboardSoundUpdateNameEvent event) {} + public void onSoundboardSoundUpdateVolume(@Nonnull SoundboardSoundUpdateVolumeEvent event) {} + public void onSoundboardSoundUpdateEmoji(@Nonnull SoundboardSoundUpdateEmojiEvent event) {} + // Entitlement events public void onEntitlementCreate(@Nonnull EntitlementCreateEvent event) {} public void onEntitlementUpdate(@Nonnull EntitlementUpdateEvent event) {} @@ -419,6 +428,7 @@ public void onGenericEmojiUpdate(@Nonnull GenericEmojiUpdateEvent event) {} public void onGenericGuildSticker(@Nonnull GenericGuildStickerEvent event) {} public void onGenericGuildStickerUpdate(@Nonnull GenericGuildStickerUpdateEvent event) {} public void onGenericSoundboardSound(@Nonnull GenericSoundboardSoundEvent event) {} + public void onGenericSoundboardSoundUpdate(@Nonnull GenericSoundboardSoundUpdateEvent event) {} public void onGenericEntitlement(@Nonnull GenericEntitlementEvent event) {} public void onGenericPermissionOverride(@Nonnull GenericPermissionOverrideEvent event) {} public void onGenericScheduledEventUpdate(@Nonnull GenericScheduledEventUpdateEvent event) {} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java index 165815f635..d766a9d6d5 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java @@ -17,6 +17,9 @@ package net.dv8tion.jda.internal.handle; import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateEmojiEvent; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateNameEvent; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateVolumeEvent; import net.dv8tion.jda.api.utils.cache.CacheFlag; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; @@ -24,6 +27,8 @@ import net.dv8tion.jda.internal.utils.UnlockHook; import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; +import java.util.Objects; + public class GuildSoundboardSoundsUpdateHandler extends SocketHandler { public GuildSoundboardSoundsUpdateHandler(JDAImpl api) @@ -63,6 +68,15 @@ protected Long handleInternally(DataObject content) soundboardSoundsView.getMap().put(soundboardSound.getIdLong(), soundboardSound); } + if (!Objects.equals(oldSoundboardSound.getName(), soundboardSound.getName())) + api.handleEvent(new SoundboardSoundUpdateNameEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getName())); + + if (oldSoundboardSound.getVolume() != soundboardSound.getVolume()) + api.handleEvent(new SoundboardSoundUpdateVolumeEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getVolume())); + + if (!Objects.equals(oldSoundboardSound.getEmoji(), soundboardSound.getEmoji())) + api.handleEvent(new SoundboardSoundUpdateEmojiEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getEmoji())); + return null; } } From b761b93e0ea3a332f45d1143957e9fcc03aa7032 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:59:33 +0200 Subject: [PATCH 13/31] Handle bulk update --- ...=> GuildSoundboardSoundCreateHandler.java} | 4 +- ...=> GuildSoundboardSoundDeleteHandler.java} | 4 +- .../GuildSoundboardSoundUpdateHandler.java | 82 +++++++++++++++++++ .../GuildSoundboardSoundsUpdateHandler.java | 39 ++------- .../internal/requests/WebSocketClient.java | 7 +- 5 files changed, 99 insertions(+), 37 deletions(-) rename src/main/java/net/dv8tion/jda/internal/handle/{GuildSoundboardSoundsCreateHandler.java => GuildSoundboardSoundCreateHandler.java} (94%) rename src/main/java/net/dv8tion/jda/internal/handle/{GuildSoundboardSoundsDeleteHandler.java => GuildSoundboardSoundDeleteHandler.java} (94%) create mode 100644 src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundUpdateHandler.java diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundCreateHandler.java similarity index 94% rename from src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java rename to src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundCreateHandler.java index 9f0e2261dd..b5b508b855 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsCreateHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundCreateHandler.java @@ -25,9 +25,9 @@ import net.dv8tion.jda.internal.utils.UnlockHook; import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; -public class GuildSoundboardSoundsCreateHandler extends SocketHandler +public class GuildSoundboardSoundCreateHandler extends SocketHandler { - public GuildSoundboardSoundsCreateHandler(JDAImpl api) + public GuildSoundboardSoundCreateHandler(JDAImpl api) { super(api); } diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundDeleteHandler.java similarity index 94% rename from src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java rename to src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundDeleteHandler.java index bb6a1d2819..d669f27dc3 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsDeleteHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundDeleteHandler.java @@ -25,9 +25,9 @@ import net.dv8tion.jda.internal.utils.UnlockHook; import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; -public class GuildSoundboardSoundsDeleteHandler extends SocketHandler +public class GuildSoundboardSoundDeleteHandler extends SocketHandler { - public GuildSoundboardSoundsDeleteHandler(JDAImpl api) + public GuildSoundboardSoundDeleteHandler(JDAImpl api) { super(api); } diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundUpdateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundUpdateHandler.java new file mode 100644 index 0000000000..02875db1ba --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundUpdateHandler.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateEmojiEvent; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateNameEvent; +import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateVolumeEvent; +import net.dv8tion.jda.api.utils.cache.CacheFlag; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.GuildImpl; +import net.dv8tion.jda.internal.utils.UnlockHook; +import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; + +import java.util.Objects; + +public class GuildSoundboardSoundUpdateHandler extends SocketHandler +{ + public GuildSoundboardSoundUpdateHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + if (!getJDA().isCacheFlagSet(CacheFlag.SOUNDBOARD_SOUNDS)) + return null; + final long guildId = content.getLong("guild_id"); + if (getJDA().getGuildSetupController().isLocked(guildId)) + return guildId; + + GuildImpl guild = (GuildImpl) getJDA().getGuildById(guildId); + if (guild == null) + { + getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + return null; + } + + SnowflakeCacheViewImpl soundboardSoundsView = guild.getSoundboardSoundsView(); + long soundId = content.getLong("sound_id"); + final SoundboardSound oldSoundboardSound = soundboardSoundsView.get(soundId); + if (oldSoundboardSound == null) + { + getJDA().getEventCache().cache(EventCache.Type.SOUNDBOARD_SOUND, soundId, responseNumber, allContent, this::handle); + EventCache.LOG.debug("Received a Guild Soundboard Sound Update for SoundboardSound that is not yet cached: {}", content); + return null; + } + + final SoundboardSound soundboardSound = api.getEntityBuilder().createSoundboardSound(content); + try (UnlockHook unlockHook = soundboardSoundsView.writeLock()) + { + soundboardSoundsView.getMap().put(soundboardSound.getIdLong(), soundboardSound); + } + + if (!Objects.equals(oldSoundboardSound.getName(), soundboardSound.getName())) + api.handleEvent(new SoundboardSoundUpdateNameEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getName())); + + if (oldSoundboardSound.getVolume() != soundboardSound.getVolume()) + api.handleEvent(new SoundboardSoundUpdateVolumeEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getVolume())); + + if (!Objects.equals(oldSoundboardSound.getEmoji(), soundboardSound.getEmoji())) + api.handleEvent(new SoundboardSoundUpdateEmojiEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getEmoji())); + + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java index d766a9d6d5..ee76328d02 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/GuildSoundboardSoundsUpdateHandler.java @@ -16,18 +16,11 @@ package net.dv8tion.jda.internal.handle; -import net.dv8tion.jda.api.entities.SoundboardSound; -import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateEmojiEvent; -import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateNameEvent; -import net.dv8tion.jda.api.events.soundboard.update.SoundboardSoundUpdateVolumeEvent; import net.dv8tion.jda.api.utils.cache.CacheFlag; +import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.GuildImpl; -import net.dv8tion.jda.internal.utils.UnlockHook; -import net.dv8tion.jda.internal.utils.cache.SnowflakeCacheViewImpl; - -import java.util.Objects; public class GuildSoundboardSoundsUpdateHandler extends SocketHandler { @@ -52,31 +45,17 @@ protected Long handleInternally(DataObject content) return null; } - SnowflakeCacheViewImpl soundboardSoundsView = guild.getSoundboardSoundsView(); - long soundId = content.getLong("sound_id"); - final SoundboardSound oldSoundboardSound = soundboardSoundsView.get(soundId); - if (oldSoundboardSound == null) - { - getJDA().getEventCache().cache(EventCache.Type.SOUNDBOARD_SOUND, soundId, responseNumber, allContent, this::handle); - EventCache.LOG.debug("Received a Guild Soundboard Sound Update for SoundboardSound that is not yet cached: {}", content); - return null; - } - - final SoundboardSound soundboardSound = api.getEntityBuilder().createSoundboardSound(content); - try (UnlockHook unlockHook = soundboardSoundsView.writeLock()) + SocketHandler handler = getJDA().getClient().getHandlers().get("GUILD_SOUNDBOARD_SOUND_UPDATE"); + DataArray array = content.getArray("soundboard_sounds"); + for (int i = 0; i < array.length(); i++) { - soundboardSoundsView.getMap().put(soundboardSound.getIdLong(), soundboardSound); + handler.handle(responseNumber, DataObject.empty() + .put("t", "GUILD_SOUNDBOARD_SOUND_UPDATE") + .put("d", array.getObject(i) + .put("guild_id", content.getLong("guild_id")) //Just in case + )); } - if (!Objects.equals(oldSoundboardSound.getName(), soundboardSound.getName())) - api.handleEvent(new SoundboardSoundUpdateNameEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getName())); - - if (oldSoundboardSound.getVolume() != soundboardSound.getVolume()) - api.handleEvent(new SoundboardSoundUpdateVolumeEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getVolume())); - - if (!Objects.equals(oldSoundboardSound.getEmoji(), soundboardSound.getEmoji())) - api.handleEvent(new SoundboardSoundUpdateEmojiEvent(api, responseNumber, soundboardSound, oldSoundboardSound.getEmoji())); - return null; } } diff --git a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java index 9f2e1d7725..7e223ebbe6 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java @@ -1397,9 +1397,10 @@ protected void setupHandlers() handlers.put("GUILD_ROLE_UPDATE", new GuildRoleUpdateHandler(api)); handlers.put("GUILD_SYNC", new GuildSyncHandler(api)); handlers.put("GUILD_STICKERS_UPDATE", new GuildStickersUpdateHandler(api)); - handlers.put("GUILD_SOUNDBOARD_SOUND_CREATE", new GuildSoundboardSoundsCreateHandler(api)); - handlers.put("GUILD_SOUNDBOARD_SOUND_UPDATE", new GuildSoundboardSoundsUpdateHandler(api)); - handlers.put("GUILD_SOUNDBOARD_SOUND_DELETE", new GuildSoundboardSoundsDeleteHandler(api)); + handlers.put("GUILD_SOUNDBOARD_SOUND_CREATE", new GuildSoundboardSoundCreateHandler(api)); + handlers.put("GUILD_SOUNDBOARD_SOUND_UPDATE", new GuildSoundboardSoundUpdateHandler(api)); + handlers.put("GUILD_SOUNDBOARD_SOUNDS_UPDATE", new GuildSoundboardSoundsUpdateHandler(api)); + handlers.put("GUILD_SOUNDBOARD_SOUND_DELETE", new GuildSoundboardSoundDeleteHandler(api)); handlers.put("GUILD_UPDATE", new GuildUpdateHandler(api)); handlers.put("INTERACTION_CREATE", new InteractionCreateHandler(api)); handlers.put("INVITE_CREATE", new InviteCreateHandler(api)); From fd1f621a666999a2e0ae1c8d9e633ee875147b77 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:48:05 +0200 Subject: [PATCH 14/31] Add getting soundboard sound by id --- .../java/net/dv8tion/jda/api/entities/Guild.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index 4626d123d7..4aa09bfedb 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -2052,6 +2052,18 @@ default List getStickersByName(@Nonnull String name, boolean ignor @Nonnull SnowflakeCacheView getStickerCache(); + @Nullable + default SoundboardSound getSoundboardSoundById(String id) + { + return getSoundboardCache().getElementById(id); + } + + @Nullable + default SoundboardSound getSoundboardSoundById(long id) + { + return getSoundboardCache().getElementById(id); + } + @Nonnull @Unmodifiable default List getSoundboardSounds() From c01d9084cca1a26204b8b61eadd376461dfe79d5 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Wed, 16 Oct 2024 23:03:20 +0200 Subject: [PATCH 15/31] Add SoundboardSoundManager --- .../jda/api/entities/SoundboardSound.java | 5 + .../api/managers/SoundboardSoundManager.java | 154 ++++++++++++++++++ .../entities/SoundboardSoundImpl.java | 11 ++ .../managers/SoundboardSoundManagerImpl.java | 149 +++++++++++++++++ 4 files changed, 319 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java create mode 100644 src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java index cf4d67af5c..425d9a022a 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -19,6 +19,7 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.managers.SoundboardSoundManager; import net.dv8tion.jda.api.requests.RestAction; import javax.annotation.CheckReturnValue; @@ -62,4 +63,8 @@ default String getUrl() @Nonnull @CheckReturnValue RestAction delete(); + + @Nonnull + @CheckReturnValue + SoundboardSoundManager getManager(); } diff --git a/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java b/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java new file mode 100644 index 0000000000..87a6dfccd7 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java @@ -0,0 +1,154 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.managers; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.emoji.Emoji; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Manager providing functionality to update one or more fields for a {@link SoundboardSound}. + * + *

Example + *

{@code
+ * manager.setVolume(0.33)
+ *        .setEmoji(null)
+ *        .queue();
+ * manager.reset(SoundboardSoundManager.VOLUME | SoundboardSoundManager.EMOJI)
+ *        .setVolume("1")
+ *        .setEmoji(Color.RED)
+ *        .queue();
+ * }
+ * + * @see SoundboardSound#getManager() + */ +public interface SoundboardSoundManager extends Manager +{ + /** Used to reset the name field */ + long NAME = 1; + /** Used to reset the volume field */ + long VOLUME = 1 << 1; + /** Used to reset the emoji field */ + long EMOJI = 1 << 2; + + /** + * Resets the fields specified by the provided bit-flag pattern. + * You can specify a combination by using a bitwise OR concat of the flag constants. + *
Example: {@code manager.reset(SoundboardSoundManager.VOLUME | SoundboardSoundManager.EMOJI);} + * + *

Flag Constants: + *

    + *
  • {@link #NAME}
  • + *
  • {@link #VOLUME}
  • + *
  • {@link #EMOJI}
  • + *
+ * + * @param fields + * Integer value containing the flags to reset. + * + * @return SoundboardSoundManager for chaining convenience + */ + @Nonnull + @Override + @CheckReturnValue + SoundboardSoundManager reset(long fields); + + /** + * Resets the fields specified by the provided bit-flag patterns. + *
Example: {@code manager.reset(SoundboardSoundManager.VOLUME | SoundboardSoundManager.EMOJI);} + * + *

Flag Constants: + *

    + *
  • {@link #NAME}
  • + *
  • {@link #VOLUME}
  • + *
  • {@link #EMOJI}
  • + *
+ * + * @param fields + * Integer values containing the flags to reset. + * + * @return SoundboardSoundManager for chaining convenience + */ + @Nonnull + @Override + @CheckReturnValue + SoundboardSoundManager reset(long... fields); + + /** + * The target {@link SoundboardSound} for this manager + * + * @return The target SoundboardSound + */ + @Nonnull + SoundboardSound getSoundboardSound(); + + /** + * The {@link Guild} this Manager's {@link SoundboardSound} is in. + * + * @return The parent {@link Guild} + */ + @Nonnull + Guild getGuild(); + + /** + * Sets the name of the selected {@link SoundboardSound}. + * + *

A role name must not be {@code null} nor less than 2 characters or more than 32 characters long! + * + * @param name + * The new name for the selected {@link SoundboardSound} + * + * @throws IllegalArgumentException + * If the provided name is {@code null} or not between 2-32 characters long + * + * @return SoundboardSoundManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + SoundboardSoundManager setName(@Nonnull String name); + + /** + * Sets the volume of the selected {@link SoundboardSound}. + * + * @param volume + * The new volume for the selected {@link SoundboardSound} + * + * @throws IllegalArgumentException + * If the provided volume is not between 0-1 + * + * @return SoundboardSoundManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + SoundboardSoundManager setVolume(double volume); + + /** + * Sets the emoji of the selected {@link SoundboardSound}. + * + * @param emoji + * The new emoji for the selected {@link SoundboardSound} + * + * @return SoundboardSoundManager for chaining convenience + */ + @Nonnull + @CheckReturnValue + SoundboardSoundManager setEmoji(@Nullable Emoji emoji); +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java index b78f87b8ee..d44647ec1d 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java @@ -25,9 +25,11 @@ import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; +import net.dv8tion.jda.api.managers.SoundboardSoundManager; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.Route; import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.managers.SoundboardSoundManagerImpl; import net.dv8tion.jda.internal.requests.RestActionImpl; import net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl; import net.dv8tion.jda.internal.utils.Checks; @@ -138,6 +140,15 @@ public RestAction delete() return new AuditableRestActionImpl<>(api, route); } + @Nonnull + @Override + public SoundboardSoundManager getManager() { + Checks.check(getGuild() != null, "Cannot delete default soundboard sounds"); + checkEditPermissions(); + + return new SoundboardSoundManagerImpl(this); + } + private void checkEditPermissions() { final Member selfMember = guild.getSelfMember(); diff --git a/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java b/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java new file mode 100644 index 0000000000..518679526a --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java @@ -0,0 +1,149 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.managers; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.emoji.CustomEmoji; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.managers.SoundboardSoundManager; +import net.dv8tion.jda.api.requests.Route; +import net.dv8tion.jda.api.utils.data.DataObject; +import okhttp3.RequestBody; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class SoundboardSoundManagerImpl extends ManagerBase implements SoundboardSoundManager +{ + private SoundboardSound soundboardSound; + private String name; + private double volume; + private Emoji emoji; + + public SoundboardSoundManagerImpl(SoundboardSound soundboardSound) + { + super(soundboardSound.getJDA(), Route.SoundboardSounds.MODIFY_GUILD_SOUNDBOARD_SOUNDS.compile(soundboardSound.getGuild().getId(), soundboardSound.getId())); + this.soundboardSound = soundboardSound; + } + + @Nonnull + @Override + @SuppressWarnings("DataFlowIssue") + public Guild getGuild() + { + return soundboardSound.getGuild(); + } + + @Nonnull + @Override + public SoundboardSound getSoundboardSound() + { + final SoundboardSound soundboardSound = getGuild().getSoundboardSoundById(this.soundboardSound.getId()); + if (soundboardSound != null) + this.soundboardSound = soundboardSound; + return this.soundboardSound; + } + + @Nonnull + @Override + @CheckReturnValue + public SoundboardSoundManagerImpl reset(long fields) + { + super.reset(fields); + if ((fields & NAME) == NAME) + this.name = null; + if ((fields & VOLUME) == VOLUME) + this.volume = 1; + if ((fields & EMOJI) == EMOJI) + this.emoji = null; + return this; + } + + @Nonnull + @Override + @CheckReturnValue + public SoundboardSoundManagerImpl reset(long... fields) + { + super.reset(fields); + return this; + } + + @Nonnull + @Override + @CheckReturnValue + public SoundboardSoundManagerImpl reset() + { + super.reset(); + this.name = null; + this.volume = 1; + this.emoji = null; + return this; + } + + @Nonnull + @Override + public SoundboardSoundManagerImpl setName(@Nonnull String name) + { + this.name = name; + set |= NAME; + return this; + } + + @Nonnull + @Override + public SoundboardSoundManagerImpl setVolume(double volume) + { + this.volume = volume; + set |= VOLUME; + return this; + } + + @Nonnull + @Override + public SoundboardSoundManagerImpl setEmoji(@Nullable Emoji emoji) + { + this.emoji = emoji; + set |= EMOJI; + return this; + } + + @Override + protected RequestBody finalizeData() + { + DataObject object = DataObject.empty().put("name", getSoundboardSound().getName()); + if (shouldUpdate(NAME)) + object.put("name", name); + if (shouldUpdate(VOLUME)) + object.put("volume", volume); + if (shouldUpdate(EMOJI)) + { + if (emoji instanceof CustomEmoji) + object.put("emoji_id", ((CustomEmoji) emoji).getId()); + else if (emoji != null) + object.put("emoji_name", emoji.getName()); + else + { + object.put("emoji_id", null); + object.put("emoji_name", null); + } + } + reset(); + return getRequestBody(object); + } +} From 6c612a8e042fd3cb022761c3ac6f44b27f34edfb Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Thu, 17 Oct 2024 00:57:56 +0200 Subject: [PATCH 16/31] Add VoiceChannelEffectSendEvent --- .../channel/concrete/VoiceChannel.java | 108 ++++++++++++++++++ .../channel/VoiceChannelEffectSendEvent.java | 49 ++++++++ .../jda/api/hooks/ListenerAdapter.java | 4 + .../handle/VoiceChannelEffectSendHandler.java | 79 +++++++++++++ .../internal/requests/WebSocketClient.java | 1 + 5 files changed, 241 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java create mode 100644 src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java index 00a5081891..12f5235494 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java @@ -17,6 +17,9 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.ISnowflake; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.channel.attribute.IAgeRestrictedChannel; import net.dv8tion.jda.api.entities.channel.attribute.ISlowmodeChannel; import net.dv8tion.jda.api.entities.channel.attribute.IVoiceStatusChannel; @@ -25,11 +28,13 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel; +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import net.dv8tion.jda.api.managers.channel.concrete.VoiceChannelManager; import net.dv8tion.jda.api.requests.restaction.ChannelAction; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; +import javax.annotation.Nullable; /** * Represents a Discord Voice GuildChannel. @@ -73,4 +78,107 @@ default ChannelAction createCopy() @Override @CheckReturnValue VoiceChannelManager getManager(); + + class Effect + { + private final VoiceChannel channel; + private final User user; + private final EmojiUnion emoji; + private final Animation animation; + private final SoundboardSound soundboardSound; + + public Effect(VoiceChannel channel, User user, EmojiUnion emoji, Animation animation, SoundboardSound soundboardSound) + { + this.channel = channel; + this.user = user; + this.emoji = emoji; + this.animation = animation; + this.soundboardSound = soundboardSound; + } + + @Nonnull + public VoiceChannel getChannel() + { + return channel; + } + + @Nonnull + public User getUser() + { + return user; + } + + @Nullable + public EmojiUnion getEmoji() + { + return emoji; + } + + @Nullable + public Animation getAnimation() + { + return animation; + } + + @Nullable + public SoundboardSound getSoundboardSound() + { + return soundboardSound; + } + + public static class Animation implements ISnowflake + { + public Animation(long id, Type type) + { + this.id = id; + this.type = type; + } + + private final long id; + private final Type type; + + @Override + public long getIdLong() + { + return id; + } + + @Nonnull + public Type getType() + { + return type; + } + + public enum Type + { + UNKNOWN(-1), + PREMIUM(0), + BASIC(1); + + private final int value; + + Type(int value) + { + this.value = value; + } + + public int getValue() + { + return value; + } + + @Nonnull + public static Type fromValue(int value) + { + for (Type type : values()) + { + if (type.value == value) + return type; + } + + return UNKNOWN; + } + } + } + } } diff --git a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java new file mode 100644 index 0000000000..eda1703308 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.channel; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; + +import javax.annotation.Nonnull; + +/** + * Indicates that a {@link VoiceChannel.Effect voice channel effect} was sent in a {@link VoiceChannel}. + */ +public class VoiceChannelEffectSendEvent extends GenericChannelEvent +{ + private final VoiceChannel.Effect effect; + + public VoiceChannelEffectSendEvent(@Nonnull JDA api, long responseNumber, Channel channel, VoiceChannel.Effect effect) + { + super(api, responseNumber, channel); + this.effect = effect; + } + + @Nonnull + public VoiceChannel getVoiceChannel() + { + return getChannel().asVoiceChannel(); + } + + @Nonnull + public VoiceChannel.Effect getEffect() + { + return effect; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java index 862d5d8566..d35e13540d 100644 --- a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java +++ b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java @@ -20,6 +20,7 @@ import net.dv8tion.jda.api.events.channel.ChannelCreateEvent; import net.dv8tion.jda.api.events.channel.ChannelDeleteEvent; import net.dv8tion.jda.api.events.channel.GenericChannelEvent; +import net.dv8tion.jda.api.events.channel.VoiceChannelEffectSendEvent; import net.dv8tion.jda.api.events.channel.forum.ForumTagAddEvent; import net.dv8tion.jda.api.events.channel.forum.ForumTagRemoveEvent; import net.dv8tion.jda.api.events.channel.forum.GenericForumTagEvent; @@ -385,6 +386,9 @@ public void onSoundboardSoundUpdateName(@Nonnull SoundboardSoundUpdateNameEvent public void onSoundboardSoundUpdateVolume(@Nonnull SoundboardSoundUpdateVolumeEvent event) {} public void onSoundboardSoundUpdateEmoji(@Nonnull SoundboardSoundUpdateEmojiEvent event) {} + // Voice channel effect events + public void onVoiceChannelEffectSend(@Nonnull VoiceChannelEffectSendEvent event) {} + // Entitlement events public void onEntitlementCreate(@Nonnull EntitlementCreateEvent event) {} public void onEntitlementUpdate(@Nonnull EntitlementUpdateEvent event) {} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java new file mode 100644 index 0000000000..f254c4f37f --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel.Effect; +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.events.channel.VoiceChannelEffectSendEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.EntityBuilder; +import net.dv8tion.jda.internal.entities.GuildImpl; + +public class VoiceChannelEffectSendHandler extends SocketHandler +{ + public VoiceChannelEffectSendHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + final long guildId = content.getLong("guild_id"); + if (getJDA().getGuildSetupController().isLocked(guildId)) + return guildId; + + GuildImpl guild = (GuildImpl) getJDA().getGuildById(guildId); + if (guild == null) + { + getJDA().getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + return null; + } + + final long channelId = content.getLong("channel_id"); + VoiceChannel channel = guild.getVoiceChannelById(channelId); + if (channel == null) + { + getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); + return null; + } + + User user = api.getUserById(content.getString("user_id")); + EmojiUnion emoji = content.optObject("emoji").map(EntityBuilder::createEmoji).orElse(null); + Effect.Animation animation = content.opt("animation_type") + .map(rawAnimationType -> + { + long animationId = content.getLong("animation_id"); + Effect.Animation.Type type = Effect.Animation.Type.fromValue(Integer.parseInt(rawAnimationType.toString())); + return new Effect.Animation(animationId, type); + }) + .orElse(null); + SoundboardSound soundboardSound = content.opt("sound_id") + .map(soundId -> guild.getSoundboardSoundById(soundId.toString())) + .orElse(null); + + Effect effect = new Effect(channel, user, emoji, animation, soundboardSound); + + api.handleEvent(new VoiceChannelEffectSendEvent(api, responseNumber, channel, effect)); + + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java index 7e223ebbe6..e518644a0f 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java @@ -1401,6 +1401,7 @@ protected void setupHandlers() handlers.put("GUILD_SOUNDBOARD_SOUND_UPDATE", new GuildSoundboardSoundUpdateHandler(api)); handlers.put("GUILD_SOUNDBOARD_SOUNDS_UPDATE", new GuildSoundboardSoundsUpdateHandler(api)); handlers.put("GUILD_SOUNDBOARD_SOUND_DELETE", new GuildSoundboardSoundDeleteHandler(api)); + handlers.put("VOICE_CHANNEL_EFFECT_SEND", new VoiceChannelEffectSendHandler(api)); handlers.put("GUILD_UPDATE", new GuildUpdateHandler(api)); handlers.put("INTERACTION_CREATE", new InteractionCreateHandler(api)); handlers.put("INVITE_CREATE", new InviteCreateHandler(api)); From 390793bde400244fed8697099df09b01b3f3a4f1 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:16:53 +0200 Subject: [PATCH 17/31] Add error responses --- .../java/net/dv8tion/jda/api/requests/ErrorResponse.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java b/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java index 024829c5a0..434a6c7a9d 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java +++ b/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java @@ -54,6 +54,7 @@ public enum ErrorResponse UNKNOWN_WEBHOOK( 10015, "Unknown Webhook"), UNKNOWN_WEBHOOK_SERVICE( 10016, "Unknown Webhook Service"), UNKNOWN_SESSION( 10020, "Unknown session"), + UNKNOWN_ASSET( 10021, "Unknown Asset"), UNKNOWN_BAN( 10026, "Unknown Ban"), UNKNOWN_SKU( 10027, "Unknown SKU"), UNKNOWN_STORE_LISTING( 10028, "Unknown Store Listing"), @@ -79,6 +80,7 @@ public enum ErrorResponse UNKNOWN_SCHEDULED_EVENT( 10070, "Unknown Scheduled Event"), UNKNOWN_SCHEDULED_EVENT_USER( 10071, "Unknown Scheduled Event User"), UNKNOWN_TAG( 10087, "Unknown Tag"), + UNKNOWN_SOUND( 10097, "Unknown sound"), BOTS_NOT_ALLOWED( 20001, "Bots cannot use this endpoint"), ONLY_BOTS_ALLOWED( 20002, "Only bots can use this endpoint"), EXPLICIT_CONTENT_CANNOT_SEND_TO_RECIPIENT(20009, "Explicit content cannot be sent to the desired recipient(s)"), @@ -114,6 +116,7 @@ public enum ErrorResponse MAX_STICKERS( 30039, "Maximum number of stickers reached"), MAX_PRUNE_REQUESTS( 30040, "Maximum number of prune requests has been reached. Try again later"), MAX_GUILD_WIDGET_UPDATES( 30042, "Maximum number of guild widget settings updates has been reached. Try again later"), + MAX_SOUNDBOARD_SOUNDS( 30045, "Maximum number of soundboard sounds reached"), MAX_OLD_MESSAGE_EDITS( 30046, "Maximum number of edits to messages older than 1 hour reached. Try again later"), MAX_PINNED_THREADS_IN_FORUM( 30047, "Maximum number of pinned threads in a forum channel has been reached"), MAX_FORUM_TAGS( 30048, "Maximum number of tags in a forum channel has been reached"), @@ -192,19 +195,25 @@ public enum ErrorResponse SERVER_MONETIZATION_DISABLED( 50097, "This server needs monetization enabled in order to perform this action"), SERVER_NOT_ENOUGH_BOOSTS( 50101, "This server needs more boosts to perform this action"), INVALID_REQUEST_BODY( 50109, "The request body contains invalid JSON."), + INVALID_FILE( 50110, "The provided file is invalid."), + INVALID_FILE_TYPE( 50123, "The provided file type is invalid."), + INVALID_FILE_EXCEEDS_MAXIMUM_LENGTH( 50124, "The provided file duration exceeds maximum of 5.2 seconds."), OWNER_CANNOT_BE_PENDING( 50131, "Owner cannot be pending member"), OWNER_TRANSFER_TO_BOT( 50132, "Ownership cannot be transferred to a bot user"), CANNOT_RESIZE_BELOW_MAXIMUM( 50138, "Failed to resize asset below the maximum size: 262144"), MIXED_PREMIUM_ROLES_FOR_EMOJI( 50144, "Cannot mix subscription and non subscription roles for an emoji"), ILLEGAL_EMOJI_CONVERSION( 50145, "Cannot convert between premium emoji and normal emoji"), UNKNOWN_UPLOADED_FILE( 50146, "Uploaded file not found"), + INVALID_EMOJI( 50151, "The specified emoji is invalid"), VOICE_MESSAGE_ADDITIONAL_CONTENT( 50159, "Voice messages do not support additional content"), VOICE_MESSAGE_TOO_MANY_AUDIO_ATTACHMENTS( 50160, "Voice messages must have a single audio attachment"), VOICE_MESSAGE_MISSING_METADATA( 50161, "Voice messages must have supporting metadata"), CANNOT_EDIT_VOICE_MESSAGE( 50162, "Voice messages cannot be edited"), CANNOT_DELETE_GUILD_INTEGRATION( 50163, "Cannot delete guild subscription integration"), + CANNOT_SEND_VOICE_EFFECT( 50167, "Cannot send voice effect when user is server muted, deafened or suppressed"), CANNOT_SEND_VOICE_MESSAGE( 50173, "You cannot send voice messages in this channel"), USER_MUST_BE_VERIFIED( 50178, "The user account must first be verified"), + INVALID_FILE_DURATION( 50192, "The provided file does not have a valid duration"), CANNOT_SEND_STICKER( 50600, "You do not have permission to send this sticker"), MFA_NOT_ENABLED( 60003, "MFA auth required but not enabled"), NO_USER_WITH_TAG_EXISTS( 80004, "No users with DiscordTag exist"), From e518d13d7c405e55d32e47e11cf6ae5a615b38ce Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:49:27 +0200 Subject: [PATCH 18/31] Restrict SoundboardSound#sendTo to VoiceChannel --- .../java/net/dv8tion/jda/api/entities/SoundboardSound.java | 4 ++-- .../dv8tion/jda/internal/entities/SoundboardSoundImpl.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java index 425d9a022a..72addaa69a 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -17,7 +17,7 @@ package net.dv8tion.jda.api.entities; import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import net.dv8tion.jda.api.managers.SoundboardSoundManager; import net.dv8tion.jda.api.requests.RestAction; @@ -58,7 +58,7 @@ default String getUrl() @Nonnull @CheckReturnValue - RestAction sendTo(AudioChannel channel); + RestAction sendTo(VoiceChannel channel); @Nonnull @CheckReturnValue diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java index d44647ec1d..8690f1b778 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java @@ -22,7 +22,7 @@ import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.SoundboardSound; import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.managers.SoundboardSoundManager; @@ -117,7 +117,7 @@ public User getUser() @Nonnull @Override - public RestAction sendTo(AudioChannel channel) + public RestAction sendTo(VoiceChannel channel) { //TODO checks DataObject data = DataObject.empty() From d9ef6fc68bf800d9be4cf99d86de7e9f2e91ad41 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:50:32 +0200 Subject: [PATCH 19/31] Fix cache getter name --- src/main/java/net/dv8tion/jda/api/entities/Guild.java | 10 +++++----- .../net/dv8tion/jda/internal/entities/GuildImpl.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index 4aa09bfedb..042965d49b 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -2055,31 +2055,31 @@ default List getStickersByName(@Nonnull String name, boolean ignor @Nullable default SoundboardSound getSoundboardSoundById(String id) { - return getSoundboardCache().getElementById(id); + return getSoundboardSoundCache().getElementById(id); } @Nullable default SoundboardSound getSoundboardSoundById(long id) { - return getSoundboardCache().getElementById(id); + return getSoundboardSoundCache().getElementById(id); } @Nonnull @Unmodifiable default List getSoundboardSounds() { - return getSoundboardCache().asList(); + return getSoundboardSoundCache().asList(); } @Nonnull @Unmodifiable default List getSoundboardSoundsByName(@Nonnull String name, boolean ignoreCase) { - return getSoundboardCache().getElementsByName(name, ignoreCase); + return getSoundboardSoundCache().getElementsByName(name, ignoreCase); } @Nonnull - SnowflakeCacheView getSoundboardCache(); + SnowflakeCacheView getSoundboardSoundCache(); /** * Retrieves an immutable list of Custom Emojis together with their respective creators. diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index bb5b051101..9c41772d34 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -828,7 +828,7 @@ public SnowflakeCacheView getStickerCache() @Nonnull @Override - public SnowflakeCacheViewImpl getSoundboardCache() + public SnowflakeCacheViewImpl getSoundboardSoundCache() { return soundboardCache; } From afba643559a027bedeb0fc7e447cd918417718a9 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:53:08 +0200 Subject: [PATCH 20/31] More checks --- .../jda/internal/entities/GuildImpl.java | 1 + .../entities/SoundboardSoundImpl.java | 34 ++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index 9c41772d34..77b443aee6 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -1974,6 +1974,7 @@ public SoundboardSoundCreateAction createSoundboardSound(@Nonnull String name, @ { checkPermission(Permission.CREATE_GUILD_EXPRESSIONS); Checks.notNull(name, "Name"); + Checks.check(name.length() >= 2 && name.length() <= 32, "Name must be between 2 and 32 characters"); Checks.notNull(file, "File"); Route.CompiledRoute route = Route.SoundboardSounds.CREATE_GUILD_SOUNDBOARD_SOUNDS.compile(getId()); return new SoundboardSoundCreateActionImpl(getJDA(), route, name, file); diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java index 8690f1b778..7089c03d1c 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java @@ -18,10 +18,7 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.SoundboardSound; -import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; @@ -119,7 +116,34 @@ public User getUser() @Override public RestAction sendTo(VoiceChannel channel) { - //TODO checks + Checks.notNull(channel, "Channel"); + + // Check speak permissions + final Guild targetGuild = channel.getGuild(); + if (!targetGuild.getSelfMember().hasPermission(channel, Permission.VOICE_SPEAK)) + throw new InsufficientPermissionException(channel, Permission.VOICE_SPEAK); + if (!targetGuild.getSelfMember().hasPermission(channel, Permission.VOICE_USE_SOUNDBOARD)) + throw new InsufficientPermissionException(channel, Permission.VOICE_USE_SOUNDBOARD); + + if (!targetGuild.equals(getGuild())) + if (!targetGuild.getSelfMember().hasPermission(channel, Permission.VOICE_USE_EXTERNAL_SOUNDS)) + throw new InsufficientPermissionException(channel, Permission.VOICE_USE_EXTERNAL_SOUNDS); + + // Check voice state if possible + if (!channel.equals(targetGuild.getAudioManager().getConnectedChannel())) + throw new IllegalStateException("You must be connected to the voice channel you want to send the sound effect to"); + final GuildVoiceState voiceState = targetGuild.getSelfMember().getVoiceState(); + if (voiceState != null) + { + if (voiceState.isSuppressed()) + throw new IllegalStateException("You cannot send sound effects while you are being suppressed"); + if (voiceState.isDeafened()) + throw new IllegalStateException("You cannot send sound effects while you are deafened"); + if (voiceState.isMuted()) + throw new IllegalStateException("You cannot send sound effects while you are muted"); + } + + // Send DataObject data = DataObject.empty() .put("sound_id", getId()); From 7612983be4b0e251d8c10893181534c2040c2239 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:53:20 +0200 Subject: [PATCH 21/31] Fix cache getter name --- src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java b/src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java index 5e12e286ad..7555d0fd34 100644 --- a/src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java +++ b/src/main/java/net/dv8tion/jda/api/utils/cache/CacheFlag.java @@ -59,7 +59,7 @@ public enum CacheFlag */ STICKER(GatewayIntent.GUILD_EXPRESSIONS), /** - * Enables cache for {@link Guild#getSoundboardCache()} + * Enables cache for {@link Guild#getSoundboardSoundCache()} * *

Requires {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent to be enabled. */ From 71032d9b06d0a20bf60c96093260ed0fe2c060bd Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:59:47 +0200 Subject: [PATCH 22/31] More checks --- .../jda/internal/entities/SoundboardSoundImpl.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java index 7089c03d1c..6b993e2566 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/SoundboardSoundImpl.java @@ -118,6 +118,10 @@ public RestAction sendTo(VoiceChannel channel) { Checks.notNull(channel, "Channel"); + // Check available + if (!isAvailable()) + throw new IllegalStateException("Cannot send an unavailable sound"); + // Check speak permissions final Guild targetGuild = channel.getGuild(); if (!targetGuild.getSelfMember().hasPermission(channel, Permission.VOICE_SPEAK)) @@ -125,9 +129,8 @@ public RestAction sendTo(VoiceChannel channel) if (!targetGuild.getSelfMember().hasPermission(channel, Permission.VOICE_USE_SOUNDBOARD)) throw new InsufficientPermissionException(channel, Permission.VOICE_USE_SOUNDBOARD); - if (!targetGuild.equals(getGuild())) - if (!targetGuild.getSelfMember().hasPermission(channel, Permission.VOICE_USE_EXTERNAL_SOUNDS)) - throw new InsufficientPermissionException(channel, Permission.VOICE_USE_EXTERNAL_SOUNDS); + if (!targetGuild.equals(getGuild()) && !targetGuild.getSelfMember().hasPermission(channel, Permission.VOICE_USE_EXTERNAL_SOUNDS)) + throw new InsufficientPermissionException(channel, Permission.VOICE_USE_EXTERNAL_SOUNDS); // Check voice state if possible if (!channel.equals(targetGuild.getAudioManager().getConnectedChannel())) From 7f0d2e9d37fc629a3c9a3d021515e723d27bbcf7 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 18 Oct 2024 00:09:59 +0200 Subject: [PATCH 23/31] More docs --- src/main/java/net/dv8tion/jda/api/JDA.java | 5 + .../net/dv8tion/jda/api/entities/Guild.java | 96 +++++++++++++++++++ .../jda/api/entities/SoundboardSound.java | 87 +++++++++++++++++ 3 files changed, 188 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/JDA.java b/src/main/java/net/dv8tion/jda/api/JDA.java index dce013a7f3..b356616478 100644 --- a/src/main/java/net/dv8tion/jda/api/JDA.java +++ b/src/main/java/net/dv8tion/jda/api/JDA.java @@ -1845,6 +1845,11 @@ default RestAction retrieveApplicationEmojiById(long emojiId) @CheckReturnValue RestAction<@Unmodifiable List> retrieveNitroStickerPacks(); + /** + * Retrieves a list of the default {@link SoundboardSound soundboard sounds}. + * + * @return {@link RestAction} - Type: List of {@link SoundboardSound} + */ @Nonnull @CheckReturnValue RestAction<@Unmodifiable List> retrieveDefaultSoundboardSounds(); diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index 042965d49b..5c6a9cee51 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -2052,18 +2052,63 @@ default List getStickersByName(@Nonnull String name, boolean ignor @Nonnull SnowflakeCacheView getStickerCache(); + /** + * Gets a {@link SoundboardSound} from this guild that has the same id as the + * one provided. + *
If there is no {@link SoundboardSound} with an id that matches the provided + * one, then this returns {@code null}. + * + *

This requires the {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled! + * + * @param id + * the sticker id + * + * @throws NumberFormatException + * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * + * @return A Soundboard sound matching the specified id + */ @Nullable default SoundboardSound getSoundboardSoundById(String id) { return getSoundboardSoundCache().getElementById(id); } + /** + * Gets a {@link SoundboardSound} from this guild that has the same id as the + * one provided. + *
If there is no {@link SoundboardSound} with an id that matches the provided + * one, then this returns {@code null}. + * + *

This requires the {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled! + * + * @param id + * the sticker id + * + * @throws NumberFormatException + * If the provided {@code id} cannot be parsed by {@link Long#parseLong(String)} + * + * @return A Soundboard sound matching the specified id + */ @Nullable default SoundboardSound getSoundboardSoundById(long id) { return getSoundboardSoundCache().getElementById(id); } + /** + * Gets all custom {@link SoundboardSound SoundboardSounds} belonging to this guild. + *
Soundboard sounds are not ordered in any specific way in the returned list. + * + *

This copies the backing store into a list. This means every call + * creates a new list with O(n) complexity. It is recommended to store this into + * a local variable or use {@link #getStickerCache()} and use its more efficient + * versions of handling these values. + * + *

This requires the {@link CacheFlag#STICKER} to be enabled! + * + * @return An immutable List of {@link SoundboardSound SoundboardSounds}. + */ @Nonnull @Unmodifiable default List getSoundboardSounds() @@ -2071,6 +2116,20 @@ default List getSoundboardSounds() return getSoundboardSoundCache().asList(); } + /** + * Gets a list of all {@link SoundboardSound SoundboardSounds} in this Guild that have the same + * name as the one provided. + *
If there are no {@link SoundboardSound SoundboardSounds} with the provided name, then this returns an empty list. + * + *

This requires the {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled! + * + * @param name + * The name used to filter the returned {@link SoundboardSound SoundboardSounds}. Without colons. + * @param ignoreCase + * Determines if the comparison ignores case when comparing. True - case insensitive. + * + * @return Possibly-empty immutable list of all Soundboard sounds that match the provided name. + */ @Nonnull @Unmodifiable default List getSoundboardSoundsByName(@Nonnull String name, boolean ignoreCase) @@ -2078,6 +2137,16 @@ default List getSoundboardSoundsByName(@Nonnull String name, bo return getSoundboardSoundCache().getElementsByName(name, ignoreCase); } + /** + * {@link SnowflakeCacheView} of all cached {@link SoundboardSound SoundboardSounds} of this Guild. + *
This does not include {@link JDA#retrieveDefaultSoundboardSounds() default sounds}. + * + *

This will be empty if {@link CacheFlag#SOUNDBOARD_SOUNDS} is disabled! + * + * @return {@link SnowflakeCacheView} - Type: {@link SoundboardSound} + * + * @see JDA#retrieveDefaultSoundboardSounds() + */ @Nonnull SnowflakeCacheView getSoundboardSoundCache(); @@ -5040,6 +5109,33 @@ default AuditableRestAction createSticker(@Nonnull String name, @N @CheckReturnValue AuditableRestAction deleteSticker(@Nonnull StickerSnowflake id); + /** + * Creates a soundboard sound in the guild. + * + *

The returned {@link RestAction} can encounter the following Discord errors: + *

    + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#INVALID_FILE_EXCEEDS_MAXIMUM_LENGTH INVALID_FILE_EXCEEDS_MAXIMUM_LENGTH} + *
    The provided file exceeds the duration of 5.2 seconds
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MAX_SOUNDBOARD_SOUNDS MAX_SOUNDBOARD_SOUNDS} + *
    The maximum amount of soundboard sounds have been created, depends on the server boosts
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#INVALID_EMOJI INVALID_EMOJI} + *
    The emoji is invalid
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#INVALID_FORM_BODY INVALID_FORM_BODY} + *
    The file is too large
  • + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#INVALID_FILE INVALID_FILE} + *
    The file is malformed
  • + *
+ * + * @param file + * The file to use as the sound, can be an MP3 or an OGG file + * + * @throws IllegalArgumentException + * If {@code null} is provided, or {@code name} is not between 2-32 characters + * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException + * If the currently logged in account does not have {@link Permission#CREATE_GUILD_EXPRESSIONS CREATE_GUILD_EXPRESSIONS} in the guild. + * + * @return {@link SoundboardSoundCreateAction} + */ @Nonnull @CheckReturnValue SoundboardSoundCreateAction createSoundboardSound(@Nonnull String name, @Nonnull FileUpload file); diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java index 72addaa69a..01494a90e4 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -17,45 +17,132 @@ package net.dv8tion.jda.api.entities; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.managers.SoundboardSoundManager; +import net.dv8tion.jda.api.requests.ErrorResponse; +import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.requests.RestAction; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import javax.annotation.Nullable; +/** + * Represents a soundboard sound, can be used in voice channels if they are {@link #isAvailable() available}. + * + * @see JDA#retrieveDefaultSoundboardSounds() + * @see Guild#getSoundboardSounds() + * @see Discord's Soundboard Docs + */ public interface SoundboardSound extends ISnowflake { /** Template for {@link #getUrl()}.*/ String SOUND_URL = "https://cdn.discordapp.com/soundboard-sounds/%s"; + /** + * Returns the {@link JDA} instance related to this SoundboardSound. + * + * @return the corresponding JDA instance + */ @Nonnull JDA getJDA(); + /** + * Returns the URL to the sound asset. + * + * @return A String representing this sound's asset + */ @Nonnull default String getUrl() { return String.format(SOUND_URL, getId()); } + /** + * The name of this sound. + * + * @return The name of this sound + */ @Nonnull String getName(); + /** + * The volume of this sound, from 0 to 1. + * + * @return The volume of this sound, from 0 to 1 + */ double getVolume(); + /** + * The emoji of this sound, or {@code null} if none is set. + * + * @return The emoji of this sound, or {@code null} + */ @Nullable EmojiUnion getEmoji(); + /** + * The guild this sound is from. + * + * @return The guild this sound is from, or {@code null} if this is a default soundboard sound + */ @Nullable Guild getGuild(); + /** + * Whether this sound can be used, may be {@code false} due to loss of server boosts. + * + * @return {@code true} if the sound can be used, {@code false} otherwise + */ boolean isAvailable(); + /** + * The user which created this sound. + * + *

This is present only if the {@link Guild#getSelfMember() current member} has + * the {@link Permission#CREATE_GUILD_EXPRESSIONS CREATE_GUILD_EXPRESSIONS} + * or {@link Permission#MANAGE_GUILD_EXPRESSIONS MANAGE_GUILD_EXPRESSIONS} permission. + * + * @return The user which created this sound, or {@code null} + */ @Nullable User getUser(); + /** + * Sends this sound to the specified voice channel. + *
You must be connected to the voice channel to use this method, + * as well as be able to speak and hear. + * + *

Possible {@link ErrorResponse ErrorResponses} caused by + * the returned {@link RestAction} include the following: + *

    + *
  • {@link ErrorResponse#MISSING_PERMISSIONS MISSING_PERMISSIONS} + *
    The sound cannot be sent due to a permission discrepancy
  • + *
  • {@link ErrorResponse#CANNOT_SEND_VOICE_EFFECT CANNOT_SEND_VOICE_EFFECT} + *
    The sound cannot be sent as the bot is either muted, deafened or suppressed
  • + *
+ * + * @param channel + * The channel to send this sound on + * + * @throws InsufficientPermissionException + * If the logged in account does not have the {@link Permission#VOICE_SPEAK VOICE_SPEAK}, + * {@link Permission#VOICE_USE_SOUNDBOARD VOICE_USE_SOUNDBOARD}, + * or {@link Permission#VOICE_USE_EXTERNAL_SOUNDS VOICE_USE_EXTERNAL_SOUNDS} permission. + * @throws IllegalArgumentException + * If the provided channel is {@code null} + * @throws IllegalStateException + *
    + *
  • If {@link GatewayIntent#GUILD_VOICE_STATES} is not enabled
  • + *
  • If the bot is not connected to the specified channel
  • + *
  • If the bot is deafened, muted or suppressed in the target guild
  • + *
+ * + * @return {@link RestAction} - Type: {@link Void} + */ @Nonnull @CheckReturnValue RestAction sendTo(VoiceChannel channel); From c92e8934b4def65c9757e2c7bfaf79ac84bb046e Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 18 Oct 2024 00:12:03 +0200 Subject: [PATCH 24/31] Move VoiceChannel.Effect to VoiceChannelEffect --- .../entities/channel/VoiceChannelEffect.java | 113 ++++++++++++++++++ .../channel/concrete/VoiceChannel.java | 107 ----------------- .../channel/VoiceChannelEffectSendEvent.java | 9 +- .../handle/VoiceChannelEffectSendHandler.java | 10 +- 4 files changed, 123 insertions(+), 116 deletions(-) create mode 100644 src/main/java/net/dv8tion/jda/api/entities/channel/VoiceChannelEffect.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/VoiceChannelEffect.java b/src/main/java/net/dv8tion/jda/api/entities/channel/VoiceChannelEffect.java new file mode 100644 index 0000000000..87983c57ac --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/VoiceChannelEffect.java @@ -0,0 +1,113 @@ +package net.dv8tion.jda.api.entities.channel; + +import net.dv8tion.jda.api.entities.ISnowflake; +import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; +import net.dv8tion.jda.api.entities.emoji.EmojiUnion; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class VoiceChannelEffect +{ + private final VoiceChannel channel; + private final User user; + private final EmojiUnion emoji; + private final Animation animation; + private final SoundboardSound soundboardSound; + + public VoiceChannelEffect(VoiceChannel channel, User user, EmojiUnion emoji, Animation animation, SoundboardSound soundboardSound) + { + this.channel = channel; + this.user = user; + this.emoji = emoji; + this.animation = animation; + this.soundboardSound = soundboardSound; + } + + @Nonnull + public VoiceChannel getChannel() + { + return channel; + } + + @Nonnull + public User getUser() + { + return user; + } + + @Nullable + public EmojiUnion getEmoji() + { + return emoji; + } + + @Nullable + public Animation getAnimation() + { + return animation; + } + + @Nullable + public SoundboardSound getSoundboardSound() + { + return soundboardSound; + } + + public static class Animation implements ISnowflake + { + public Animation(long id, Animation.Type type) + { + this.id = id; + this.type = type; + } + + private final long id; + private final Animation.Type type; + + @Override + public long getIdLong() + { + return id; + } + + @Nonnull + public Animation.Type getType() + { + return type; + } + + public enum Type + { + UNKNOWN(-1), + PREMIUM(0), + BASIC(1); + + private final int value; + + Type(int value) + { + this.value = value; + } + + public int getValue() + { + return value; + } + + @Nonnull + public static Animation.Type fromValue(int value) + { + for (Animation.Type type : values()) + { + if (type.value == value) + return type; + } + + return UNKNOWN; + } + } + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java index 12f5235494..f45f1ecf89 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java @@ -17,9 +17,6 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.ISnowflake; -import net.dv8tion.jda.api.entities.SoundboardSound; -import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.channel.attribute.IAgeRestrictedChannel; import net.dv8tion.jda.api.entities.channel.attribute.ISlowmodeChannel; import net.dv8tion.jda.api.entities.channel.attribute.IVoiceStatusChannel; @@ -28,13 +25,11 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel; -import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import net.dv8tion.jda.api.managers.channel.concrete.VoiceChannelManager; import net.dv8tion.jda.api.requests.restaction.ChannelAction; import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * Represents a Discord Voice GuildChannel. @@ -79,106 +74,4 @@ default ChannelAction createCopy() @CheckReturnValue VoiceChannelManager getManager(); - class Effect - { - private final VoiceChannel channel; - private final User user; - private final EmojiUnion emoji; - private final Animation animation; - private final SoundboardSound soundboardSound; - - public Effect(VoiceChannel channel, User user, EmojiUnion emoji, Animation animation, SoundboardSound soundboardSound) - { - this.channel = channel; - this.user = user; - this.emoji = emoji; - this.animation = animation; - this.soundboardSound = soundboardSound; - } - - @Nonnull - public VoiceChannel getChannel() - { - return channel; - } - - @Nonnull - public User getUser() - { - return user; - } - - @Nullable - public EmojiUnion getEmoji() - { - return emoji; - } - - @Nullable - public Animation getAnimation() - { - return animation; - } - - @Nullable - public SoundboardSound getSoundboardSound() - { - return soundboardSound; - } - - public static class Animation implements ISnowflake - { - public Animation(long id, Type type) - { - this.id = id; - this.type = type; - } - - private final long id; - private final Type type; - - @Override - public long getIdLong() - { - return id; - } - - @Nonnull - public Type getType() - { - return type; - } - - public enum Type - { - UNKNOWN(-1), - PREMIUM(0), - BASIC(1); - - private final int value; - - Type(int value) - { - this.value = value; - } - - public int getValue() - { - return value; - } - - @Nonnull - public static Type fromValue(int value) - { - for (Type type : values()) - { - if (type.value == value) - return type; - } - - return UNKNOWN; - } - } - } - } } diff --git a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java index eda1703308..43c5674145 100644 --- a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java @@ -18,18 +18,19 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.entities.channel.VoiceChannelEffect; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; import javax.annotation.Nonnull; /** - * Indicates that a {@link VoiceChannel.Effect voice channel effect} was sent in a {@link VoiceChannel}. + * Indicates that a {@link VoiceChannelEffect voice channel effect} was sent in a {@link VoiceChannel}. */ public class VoiceChannelEffectSendEvent extends GenericChannelEvent { - private final VoiceChannel.Effect effect; + private final VoiceChannelEffect effect; - public VoiceChannelEffectSendEvent(@Nonnull JDA api, long responseNumber, Channel channel, VoiceChannel.Effect effect) + public VoiceChannelEffectSendEvent(@Nonnull JDA api, long responseNumber, Channel channel, VoiceChannelEffect effect) { super(api, responseNumber, channel); this.effect = effect; @@ -42,7 +43,7 @@ public VoiceChannel getVoiceChannel() } @Nonnull - public VoiceChannel.Effect getEffect() + public VoiceChannelEffect getEffect() { return effect; } diff --git a/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java index f254c4f37f..f1471553d1 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java @@ -18,8 +18,8 @@ import net.dv8tion.jda.api.entities.SoundboardSound; import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.VoiceChannelEffect; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; -import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel.Effect; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; import net.dv8tion.jda.api.events.channel.VoiceChannelEffectSendEvent; import net.dv8tion.jda.api.utils.data.DataObject; @@ -58,19 +58,19 @@ protected Long handleInternally(DataObject content) User user = api.getUserById(content.getString("user_id")); EmojiUnion emoji = content.optObject("emoji").map(EntityBuilder::createEmoji).orElse(null); - Effect.Animation animation = content.opt("animation_type") + VoiceChannelEffect.Animation animation = content.opt("animation_type") .map(rawAnimationType -> { long animationId = content.getLong("animation_id"); - Effect.Animation.Type type = Effect.Animation.Type.fromValue(Integer.parseInt(rawAnimationType.toString())); - return new Effect.Animation(animationId, type); + VoiceChannelEffect.Animation.Type type = VoiceChannelEffect.Animation.Type.fromValue(Integer.parseInt(rawAnimationType.toString())); + return new VoiceChannelEffect.Animation(animationId, type); }) .orElse(null); SoundboardSound soundboardSound = content.opt("sound_id") .map(soundId -> guild.getSoundboardSoundById(soundId.toString())) .orElse(null); - Effect effect = new Effect(channel, user, emoji, animation, soundboardSound); + VoiceChannelEffect effect = new VoiceChannelEffect(channel, user, emoji, animation, soundboardSound); api.handleEvent(new VoiceChannelEffectSendEvent(api, responseNumber, channel, effect)); From e8c90ffa2cacecd0a939d3cf14925f44b07fb46c Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 18 Oct 2024 00:14:29 +0200 Subject: [PATCH 25/31] Nullable emoji while creating --- .../api/requests/restaction/SoundboardSoundCreateAction.java | 2 +- .../requests/restaction/SoundboardSoundCreateActionImpl.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java index b884626f6a..d27f8c520e 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java @@ -57,5 +57,5 @@ public interface SoundboardSoundCreateAction extends AuditableRestAction Date: Fri, 18 Oct 2024 00:16:39 +0200 Subject: [PATCH 26/31] Add checks to manager --- .../jda/internal/managers/SoundboardSoundManagerImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java b/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java index 518679526a..d18d87d9ae 100644 --- a/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java @@ -23,6 +23,7 @@ import net.dv8tion.jda.api.managers.SoundboardSoundManager; import net.dv8tion.jda.api.requests.Route; import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.utils.Checks; import okhttp3.RequestBody; import javax.annotation.CheckReturnValue; @@ -100,6 +101,7 @@ public SoundboardSoundManagerImpl reset() @Override public SoundboardSoundManagerImpl setName(@Nonnull String name) { + Checks.check(name.length() >= 2 && name.length() <= 32, "Name must be between 2 and 32 characters"); this.name = name; set |= NAME; return this; @@ -109,6 +111,7 @@ public SoundboardSoundManagerImpl setName(@Nonnull String name) @Override public SoundboardSoundManagerImpl setVolume(double volume) { + Checks.check(volume >= 0 && volume <= 1, "Volume must be between 0 and 1"); this.volume = volume; set |= VOLUME; return this; From cda847b185b5835a7fbf7aa8e641be7542980fa5 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:18:16 +0200 Subject: [PATCH 27/31] Add missing check --- .../jda/internal/managers/SoundboardSoundManagerImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java b/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java index d18d87d9ae..f1fcb9ae73 100644 --- a/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/managers/SoundboardSoundManagerImpl.java @@ -101,6 +101,7 @@ public SoundboardSoundManagerImpl reset() @Override public SoundboardSoundManagerImpl setName(@Nonnull String name) { + Checks.notNull(name, "name"); Checks.check(name.length() >= 2 && name.length() <= 32, "Name must be between 2 and 32 characters"); this.name = name; set |= NAME; From 235764775ba19aa57cd2e8572401dbc373711a9c Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:18:44 +0200 Subject: [PATCH 28/31] Improve docs --- src/main/java/net/dv8tion/jda/api/JDA.java | 2 +- .../net/dv8tion/jda/api/entities/Guild.java | 16 ++++-- .../jda/api/entities/SoundboardSound.java | 55 +++++++++++++++++-- .../soundboard/update/package-info.java | 2 +- .../api/managers/SoundboardSoundManager.java | 4 +- 5 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/JDA.java b/src/main/java/net/dv8tion/jda/api/JDA.java index b356616478..88d44aa98a 100644 --- a/src/main/java/net/dv8tion/jda/api/JDA.java +++ b/src/main/java/net/dv8tion/jda/api/JDA.java @@ -1846,7 +1846,7 @@ default RestAction retrieveApplicationEmojiById(long emojiId) RestAction<@Unmodifiable List> retrieveNitroStickerPacks(); /** - * Retrieves a list of the default {@link SoundboardSound soundboard sounds}. + * Retrieves a list of the default {@link SoundboardSound SoundboardSounds}. * * @return {@link RestAction} - Type: List of {@link SoundboardSound} */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index 5c6a9cee51..7eae91c33d 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -2102,10 +2102,10 @@ default SoundboardSound getSoundboardSoundById(long id) * *

This copies the backing store into a list. This means every call * creates a new list with O(n) complexity. It is recommended to store this into - * a local variable or use {@link #getStickerCache()} and use its more efficient + * a local variable or use {@link #getSoundboardSoundCache()} and use its more efficient * versions of handling these values. * - *

This requires the {@link CacheFlag#STICKER} to be enabled! + *

This requires the {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled! * * @return An immutable List of {@link SoundboardSound SoundboardSounds}. */ @@ -2128,7 +2128,7 @@ default List getSoundboardSounds() * @param ignoreCase * Determines if the comparison ignores case when comparing. True - case insensitive. * - * @return Possibly-empty immutable list of all Soundboard sounds that match the provided name. + * @return Possibly-empty immutable list of all SoundboardSounds that match the provided name. */ @Nonnull @Unmodifiable @@ -5112,7 +5112,7 @@ default AuditableRestAction createSticker(@Nonnull String name, @N /** * Creates a soundboard sound in the guild. * - *

The returned {@link RestAction} can encounter the following Discord errors: + *

The returned {@link RestAction} can encounter the following {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses}: *

    *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#INVALID_FILE_EXCEEDS_MAXIMUM_LENGTH INVALID_FILE_EXCEEDS_MAXIMUM_LENGTH} *
    The provided file exceeds the duration of 5.2 seconds
  • @@ -5126,11 +5126,17 @@ default AuditableRestAction createSticker(@Nonnull String name, @N *
    The file is malformed *
* + * @param name + * The name of the soundboard sound, must be between 2-32 characters * @param file * The file to use as the sound, can be an MP3 or an OGG file * * @throws IllegalArgumentException - * If {@code null} is provided, or {@code name} is not between 2-32 characters + *
    + *
  • If {@code null} is provided
  • + *
  • If {@code name} is not between 2-32 characters
  • + *
  • If the file is not of the correct type
  • + *
* @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If the currently logged in account does not have {@link Permission#CREATE_GUILD_EXPRESSIONS CREATE_GUILD_EXPRESSIONS} in the guild. * diff --git a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java index 01494a90e4..6221ac27ae 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java +++ b/src/main/java/net/dv8tion/jda/api/entities/SoundboardSound.java @@ -102,7 +102,7 @@ default String getUrl() /** * The user which created this sound. * - *

This is present only if the {@link Guild#getSelfMember() current member} has + *

This is present only if the {@link Guild#getSelfMember() self member} has * the {@link Permission#CREATE_GUILD_EXPRESSIONS CREATE_GUILD_EXPRESSIONS} * or {@link Permission#MANAGE_GUILD_EXPRESSIONS MANAGE_GUILD_EXPRESSIONS} permission. * @@ -116,27 +116,31 @@ default String getUrl() *
You must be connected to the voice channel to use this method, * as well as be able to speak and hear. * - *

Possible {@link ErrorResponse ErrorResponses} caused by - * the returned {@link RestAction} include the following: + *

The returned {@link RestAction} can encounter the following {@link ErrorResponse ErrorResponses}: *

    *
  • {@link ErrorResponse#MISSING_PERMISSIONS MISSING_PERMISSIONS} *
    The sound cannot be sent due to a permission discrepancy
  • *
  • {@link ErrorResponse#CANNOT_SEND_VOICE_EFFECT CANNOT_SEND_VOICE_EFFECT} *
    The sound cannot be sent as the bot is either muted, deafened or suppressed
  • + *
  • {@link ErrorResponse#UNKNOWN_SOUND UNKNOWN_SOUND} + *
    The sound was deleted
  • *
* * @param channel * The channel to send this sound on * * @throws InsufficientPermissionException - * If the logged in account does not have the {@link Permission#VOICE_SPEAK VOICE_SPEAK}, - * {@link Permission#VOICE_USE_SOUNDBOARD VOICE_USE_SOUNDBOARD}, - * or {@link Permission#VOICE_USE_EXTERNAL_SOUNDS VOICE_USE_EXTERNAL_SOUNDS} permission. + * If the bot does not have the following permissions: + *
    + *
  • {@link Permission#VOICE_SPEAK VOICE_SPEAK}, {@link Permission#VOICE_USE_SOUNDBOARD VOICE_USE_SOUNDBOARD}
  • + *
  • When used in other guilds, {@link Permission#VOICE_USE_EXTERNAL_SOUNDS VOICE_USE_EXTERNAL_SOUNDS} permission
  • + *
* @throws IllegalArgumentException * If the provided channel is {@code null} * @throws IllegalStateException *
    *
  • If {@link GatewayIntent#GUILD_VOICE_STATES} is not enabled
  • + *
  • If the sound is not {@link #isAvailable() available}
  • *
  • If the bot is not connected to the specified channel
  • *
  • If the bot is deafened, muted or suppressed in the target guild
  • *
@@ -147,10 +151,49 @@ default String getUrl() @CheckReturnValue RestAction sendTo(VoiceChannel channel); + /** + * Deletes this soundboard sound. + * + *

The returned {@link RestAction} can encounter the following {@link ErrorResponse ErrorResponses}: + *

    + *
  • {@link ErrorResponse#MISSING_PERMISSIONS MISSING_PERMISSIONS} + *
    The sound cannot be deleted due to a permission discrepancy
  • + *
  • {@link ErrorResponse#UNKNOWN_SOUND UNKNOWN_SOUND} + *
    The sound was deleted
  • + *
+ * + * @throws InsufficientPermissionException + *
    + *
  • If the bot does not own this sound and does not have {@link Permission#MANAGE_GUILD_EXPRESSIONS}
  • + *
  • If the bot owns this sound and does not have {@link Permission#MANAGE_GUILD_EXPRESSIONS} or {@link Permission#CREATE_GUILD_EXPRESSIONS}
  • + *
+ * + * @return {@link RestAction} - Type: {@link Void} + */ @Nonnull @CheckReturnValue RestAction delete(); + /** + * The {@link SoundboardSoundManager} for this soundboard sound, in which you can modify values. + *
You modify multiple fields in one request by chaining setters before calling {@link RestAction#queue()}. + * + *

The returned {@link RestAction} can encounter the following {@link ErrorResponse ErrorResponses}: + *

    + *
  • {@link ErrorResponse#MISSING_PERMISSIONS MISSING_PERMISSIONS} + *
    The sound cannot be edited due to a permission discrepancy
  • + *
  • {@link ErrorResponse#UNKNOWN_SOUND UNKNOWN_SOUND} + *
    The sound was deleted
  • + *
+ * + * @throws InsufficientPermissionException + *
    + *
  • If the bot does not own this sound and does not have {@link Permission#MANAGE_GUILD_EXPRESSIONS}
  • + *
  • If the bot owns this sound and does not have {@link Permission#MANAGE_GUILD_EXPRESSIONS} or {@link Permission#CREATE_GUILD_EXPRESSIONS}
  • + *
+ * + * @return The SoundboardSoundManager of this soundboard sound + */ @Nonnull @CheckReturnValue SoundboardSoundManager getManager(); diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java index 9da41434aa..5a26ea9abc 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java @@ -15,7 +15,7 @@ */ /** - * Events that track updates for existing {@link net.dv8tion.jda.api.entities.SoundboardSound Soundboard sounds} + * Events that track updates for existing {@link net.dv8tion.jda.api.entities.SoundboardSound SoundboardSounds} * *

Requirements
* diff --git a/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java b/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java index 87a6dfccd7..f488612bd8 100644 --- a/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java +++ b/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java @@ -33,8 +33,8 @@ * .setEmoji(null) * .queue(); * manager.reset(SoundboardSoundManager.VOLUME | SoundboardSoundManager.EMOJI) - * .setVolume("1") - * .setEmoji(Color.RED) + * .setVolume(1) + * .setEmoji(Emoji.fromUnicode("🤔")) * .queue(); * } * From 78994a1cfd214c93ecc00c767c89f968b722cbf9 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:22:06 +0200 Subject: [PATCH 29/31] Event docs --- .../events/channel/VoiceChannelEffectSendEvent.java | 4 ++++ .../soundboard/GenericSoundboardSoundEvent.java | 12 ++++++++++++ .../soundboard/SoundboardSoundCreateEvent.java | 12 ++++++++++++ .../soundboard/SoundboardSoundDeleteEvent.java | 12 ++++++++++++ .../jda/api/events/soundboard/package-info.java | 5 ++--- .../update/GenericSoundboardSoundUpdateEvent.java | 12 +++++++----- .../update/SoundboardSoundUpdateEmojiEvent.java | 12 +++++++----- .../update/SoundboardSoundUpdateNameEvent.java | 12 +++++++----- .../update/SoundboardSoundUpdateVolumeEvent.java | 12 +++++++----- .../api/events/soundboard/update/package-info.java | 5 ++--- 10 files changed, 72 insertions(+), 26 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java index 43c5674145..f11c390ee9 100644 --- a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java @@ -20,11 +20,15 @@ import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.VoiceChannelEffect; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; +import net.dv8tion.jda.api.requests.GatewayIntent; import javax.annotation.Nonnull; /** * Indicates that a {@link VoiceChannelEffect voice channel effect} was sent in a {@link VoiceChannel}. + * + *

Requirements
+ * This event requires {@link GatewayIntent#GUILD_VOICE_STATES} to be enabled. */ public class VoiceChannelEffectSendEvent extends GenericChannelEvent { diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/GenericSoundboardSoundEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/GenericSoundboardSoundEvent.java index a065e6b594..21ff3890a0 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/GenericSoundboardSoundEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/GenericSoundboardSoundEvent.java @@ -17,12 +17,24 @@ package net.dv8tion.jda.api.events.soundboard; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.SoundboardSound; import net.dv8tion.jda.api.events.Event; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.cache.CacheFlag; import javax.annotation.Nonnull; +/** + * Indicates that a {@link SoundboardSound} was created/deleted/updated. + * + *

Requirements
+ * These events require {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. + * + *
{@link JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + */ public abstract class GenericSoundboardSoundEvent extends Event { private final SoundboardSound soundboardSound; diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundCreateEvent.java index 073b1f1f11..a12f875bec 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundCreateEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundCreateEvent.java @@ -17,10 +17,22 @@ package net.dv8tion.jda.api.events.soundboard; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.cache.CacheFlag; import javax.annotation.Nonnull; +/** + * Indicates that a {@link SoundboardSound} was created. + * + *

Requirements
+ * This event require {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. + * + *
{@link JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + */ public class SoundboardSoundCreateEvent extends GenericSoundboardSoundEvent { public SoundboardSoundCreateEvent(@Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound) diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundDeleteEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundDeleteEvent.java index 9828e5b70c..3bc1af2024 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundDeleteEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/SoundboardSoundDeleteEvent.java @@ -17,10 +17,22 @@ package net.dv8tion.jda.api.events.soundboard; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.cache.CacheFlag; import javax.annotation.Nonnull; +/** + * Indicates that a {@link SoundboardSound} was deleted. + * + *

Requirements
+ * This event require {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. + * + *
{@link JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + */ public class SoundboardSoundDeleteEvent extends GenericSoundboardSoundEvent { public SoundboardSoundDeleteEvent(@Nonnull JDA api, long responseNumber, @Nonnull SoundboardSound soundboardSound) diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/package-info.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/package-info.java index 0cf5c8c3ea..0b04068923 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/package-info.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/package-info.java @@ -19,9 +19,8 @@ * and {@link net.dv8tion.jda.api.events.soundboard.SoundboardSoundDeleteEvent deleted soundboard sounds}. * *

Requirements
- * - *

These events require the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires - * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. + * These events require {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. * *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! */ diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/GenericSoundboardSoundUpdateEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/GenericSoundboardSoundUpdateEvent.java index 6b5cb967bd..4cf0edc9e1 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/GenericSoundboardSoundUpdateEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/GenericSoundboardSoundUpdateEvent.java @@ -17,22 +17,24 @@ package net.dv8tion.jda.api.events.soundboard.update; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.SoundboardSound; import net.dv8tion.jda.api.events.UpdateEvent; import net.dv8tion.jda.api.events.soundboard.GenericSoundboardSoundEvent; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.cache.CacheFlag; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** - * Indicates that a {@link SoundboardSound soundboard sound} was updated. + * Indicates that a {@link SoundboardSound} was updated. * *

Requirements
+ * These events require {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. * - *

These events require the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires - * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. - * - *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + *
{@link JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! */ public abstract class GenericSoundboardSoundUpdateEvent extends GenericSoundboardSoundEvent implements UpdateEvent { diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateEmojiEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateEmojiEvent.java index 613776909a..f9e51587c3 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateEmojiEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateEmojiEvent.java @@ -17,8 +17,11 @@ package net.dv8tion.jda.api.events.soundboard.update; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.SoundboardSound; import net.dv8tion.jda.api.entities.emoji.EmojiUnion; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.cache.CacheFlag; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -26,14 +29,13 @@ /** * Indicates that the emoji of a {@link SoundboardSound soundboard sound} changed. * - *

Can be used to retrieve the old emoji + *

Can be used to retrieve the old emoji. * *

Requirements
+ * This event require {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. * - *

This event requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires - * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. - * - *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + *
{@link JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! * *

Identifier: {@value IDENTIFIER} */ diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateNameEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateNameEvent.java index 53e7fe5dcb..e0ddbe21e3 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateNameEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateNameEvent.java @@ -17,21 +17,23 @@ package net.dv8tion.jda.api.events.soundboard.update; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.cache.CacheFlag; import javax.annotation.Nonnull; /** * Indicates that the name of a {@link SoundboardSound soundboard sound} changed. * - *

Can be used to retrieve the old name + *

Can be used to retrieve the old name. * *

Requirements
+ * This event require {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. * - *

This event requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires - * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. - * - *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + *
{@link JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! * *

Identifier: {@value IDENTIFIER} */ diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateVolumeEvent.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateVolumeEvent.java index 8e8eb18742..fd3ee8dc03 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateVolumeEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/SoundboardSoundUpdateVolumeEvent.java @@ -17,21 +17,23 @@ package net.dv8tion.jda.api.events.soundboard.update; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.SoundboardSound; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.cache.CacheFlag; import javax.annotation.Nonnull; /** * Indicates that the volume of a {@link SoundboardSound soundboard sound} changed. * - *

Can be used to retrieve the old volume + *

Can be used to retrieve the old volume. * *

Requirements
+ * This event require {@link CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. * - *

This event requires the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires - * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. - * - *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! + *
{@link JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! * *

Identifier: {@value IDENTIFIER} */ diff --git a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java index 5a26ea9abc..8083e7d57e 100644 --- a/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java +++ b/src/main/java/net/dv8tion/jda/api/events/soundboard/update/package-info.java @@ -18,9 +18,8 @@ * Events that track updates for existing {@link net.dv8tion.jda.api.entities.SoundboardSound SoundboardSounds} * *

Requirements
- * - *

These events require the {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS SOUNDBOARD_SOUNDS} CacheFlag to be enabled, which requires - * the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS GUILD_EMOJIS_AND_STICKERS} intent. + * These events require {@link net.dv8tion.jda.api.utils.cache.CacheFlag#SOUNDBOARD_SOUNDS} to be enabled, + * which requires {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_EMOJIS_AND_STICKERS}. * *
{@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disables that CacheFlag by default! */ From f9245b4ce21135a573a5b1747e6d3170b2e44739 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:40:57 +0200 Subject: [PATCH 30/31] Clean up voice channel effect send --- .../jda/api/entities/channel/concrete/VoiceChannel.java | 1 - .../api/events/channel/VoiceChannelEffectSendEvent.java | 7 +++---- .../jda/internal/handle/VoiceChannelEffectSendHandler.java | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java index f45f1ecf89..00a5081891 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/VoiceChannel.java @@ -73,5 +73,4 @@ default ChannelAction createCopy() @Override @CheckReturnValue VoiceChannelManager getManager(); - } diff --git a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java index f11c390ee9..afc59da61b 100644 --- a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java @@ -17,7 +17,6 @@ package net.dv8tion.jda.api.events.channel; import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.VoiceChannelEffect; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; import net.dv8tion.jda.api.requests.GatewayIntent; @@ -34,16 +33,16 @@ public class VoiceChannelEffectSendEvent extends GenericChannelEvent { private final VoiceChannelEffect effect; - public VoiceChannelEffectSendEvent(@Nonnull JDA api, long responseNumber, Channel channel, VoiceChannelEffect effect) + public VoiceChannelEffectSendEvent(@Nonnull JDA api, long responseNumber, VoiceChannelEffect effect) { - super(api, responseNumber, channel); + super(api, responseNumber, effect.getChannel()); this.effect = effect; } @Nonnull public VoiceChannel getVoiceChannel() { - return getChannel().asVoiceChannel(); + return effect.getChannel(); } @Nonnull diff --git a/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java index f1471553d1..dc5620df1e 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/VoiceChannelEffectSendHandler.java @@ -72,7 +72,7 @@ protected Long handleInternally(DataObject content) VoiceChannelEffect effect = new VoiceChannelEffect(channel, user, emoji, animation, soundboardSound); - api.handleEvent(new VoiceChannelEffectSendEvent(api, responseNumber, channel, effect)); + api.handleEvent(new VoiceChannelEffectSendEvent(api, responseNumber, effect)); return null; } From 0fd3723512e7054a5dfd6075080fe3efc93c1c54 Mon Sep 17 00:00:00 2001 From: freya02 <41875020+freya022@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:42:06 +0200 Subject: [PATCH 31/31] Last docs --- .../entities/channel/VoiceChannelEffect.java | 52 +++++++++++++++++++ .../channel/VoiceChannelEffectSendEvent.java | 10 ++++ .../api/managers/SoundboardSoundManager.java | 2 +- .../SoundboardSoundCreateAction.java | 19 +++++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/VoiceChannelEffect.java b/src/main/java/net/dv8tion/jda/api/entities/channel/VoiceChannelEffect.java index 87983c57ac..9071497f81 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/VoiceChannelEffect.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/VoiceChannelEffect.java @@ -9,6 +9,9 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +/** + * Represents an emoji effect or a soundboard sound effect. + */ public class VoiceChannelEffect { private final VoiceChannel channel; @@ -26,36 +29,64 @@ public VoiceChannelEffect(VoiceChannel channel, User user, EmojiUnion emoji, Ani this.soundboardSound = soundboardSound; } + /** + * The voice channel this effect was sent to. + * + * @return The voice channel this effect was sent to. + */ @Nonnull public VoiceChannel getChannel() { return channel; } + /** + * The user which sent this effect. + * + * @return The user which sent this effect. + */ @Nonnull public User getUser() { return user; } + /** + * The emoji sent with the effect, this is only present for emoji effects. + * + * @return The emoji sent with the effect, or {@code null} + */ @Nullable public EmojiUnion getEmoji() { return emoji; } + /** + * The animation of the emoji, this is only present for emoji effects. + * + * @return The animation of the emoji, or {@code null} + */ @Nullable public Animation getAnimation() { return animation; } + /** + * The soundboard sound sent with the effect, this is only present for soundboard sound effects. + * + * @return The soundboard sound sent with the effect, or {@code null} + */ @Nullable public SoundboardSound getSoundboardSound() { return soundboardSound; } + /** + * Represents the animation used in emoji effects. + */ public static class Animation implements ISnowflake { public Animation(long id, Animation.Type type) @@ -73,12 +104,20 @@ public long getIdLong() return id; } + /** + * The type of animation + * + * @return The type of animation + */ @Nonnull public Animation.Type getType() { return type; } + /** + * Represents the animation type used in emoji effects. + */ public enum Type { UNKNOWN(-1), @@ -92,11 +131,24 @@ public enum Type this.value = value; } + /** + * The raw value of this animation type. + * + * @return The raw value + */ public int getValue() { return value; } + /** + * Retrieves the animation type from the raw value. + * + * @param value + * The raw value of the animation type + * + * @return The animation type, or {@link #UNKNOWN} for invalid values + */ @Nonnull public static Animation.Type fromValue(int value) { diff --git a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java index afc59da61b..b68372c6b1 100644 --- a/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/channel/VoiceChannelEffectSendEvent.java @@ -39,12 +39,22 @@ public VoiceChannelEffectSendEvent(@Nonnull JDA api, long responseNumber, VoiceC this.effect = effect; } + /** + * The voice channel the effect was sent to. + * + * @return The voice channel the effect was sent to. + */ @Nonnull public VoiceChannel getVoiceChannel() { return effect.getChannel(); } + /** + * The effect that was sent. + * + * @return The effect that was sent. + */ @Nonnull public VoiceChannelEffect getEffect() { diff --git a/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java b/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java index f488612bd8..0382e085ae 100644 --- a/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java +++ b/src/main/java/net/dv8tion/jda/api/managers/SoundboardSoundManager.java @@ -144,7 +144,7 @@ public interface SoundboardSoundManager extends Manager * Sets the emoji of the selected {@link SoundboardSound}. * * @param emoji - * The new emoji for the selected {@link SoundboardSound} + * The new emoji for the selected {@link SoundboardSound}, can be {@code null} * * @return SoundboardSoundManager for chaining convenience */ diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java index d27f8c520e..235ccdff14 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/SoundboardSoundCreateAction.java @@ -51,10 +51,29 @@ public interface SoundboardSoundCreateAction extends AuditableRestActionvolume of the soundboard sound being created. + * + * @param volume + * The new volume + * + * @throws IllegalArgumentException + * If the provided volume is not between 0-1 + * + * @return This action for chaining convenience + */ @Nonnull @CheckReturnValue SoundboardSoundCreateAction setVolume(double volume); + /** + * Sets the emoji of the soundboard sound being created. + * + * @param emoji + * The new emoji, can be {@code null} + * + * @return This action for chaining convenience + */ @Nonnull @CheckReturnValue SoundboardSoundCreateAction setEmoji(@Nullable Emoji emoji);