From e3cd724e47f3cf59608b13ebf30f871b18b10af9 Mon Sep 17 00:00:00 2001 From: Daniel Villavicencio Date: Thu, 16 May 2024 02:46:58 -0700 Subject: [PATCH] Added raid maps for all encounters in Vault of Glass --- .gitignore | 1 + build.gradle | 2 +- compose.yml | 60 ++++++++++++++++++ .../deahtstroke/rivenbot/dto/SocialLink.java | 23 +++++++ .../rivenbot/dto/discord/Emoji.java | 2 + .../com/deahtstroke/rivenbot/enums/Raid.java | 33 +++++++--- .../rivenbot/enums/SocialPlatform.java | 24 +++++++ ...tion.java => ImageRetrievalException.java} | 4 +- .../rivenbot/handler/InteractionHandler.java | 8 +-- .../rivenbot/handler/RaidMapHandler.java | 56 +++++++++------- .../service/RaidInfographicsService.java | 34 +++++----- .../rivenbot/util/HttpResponseUtils.java | 4 +- .../raids/vault_of_glass/atheon/atheon.jpg | Bin 0 -> 322782 bytes .../vault_of_glass/atheon/atheon_oracles.jpg | Bin 0 -> 222360 bytes .../vault_of_glass/confluxes/confluxes.jpg | Bin 0 -> 344815 bytes .../vault_of_glass/gatekeeper/gatekeepers.jpg | Bin 0 -> 300822 bytes .../vault_of_glass/gatekeeper/venus_mars.jpg | Bin 0 -> 200189 bytes .../gorgons_labrynth/gorgons_labrynth.jpg | Bin 0 -> 451588 bytes .../raids/vault_of_glass/oracles/oracles.jpg | Bin 0 -> 328867 bytes .../raids/vault_of_glass/templar/templar.jpg | Bin 0 -> 329130 bytes .../service/RaidInfographicsServiceTest.java | 4 +- .../rivenbot/util/HttpUtilTest.java | 4 +- 22 files changed, 195 insertions(+), 64 deletions(-) create mode 100644 compose.yml create mode 100644 src/main/java/com/deahtstroke/rivenbot/dto/SocialLink.java create mode 100644 src/main/java/com/deahtstroke/rivenbot/enums/SocialPlatform.java rename src/main/java/com/deahtstroke/rivenbot/exception/{ImageProcessingException.java => ImageRetrievalException.java} (54%) create mode 100644 src/main/resources/static/raids/vault_of_glass/atheon/atheon.jpg create mode 100644 src/main/resources/static/raids/vault_of_glass/atheon/atheon_oracles.jpg create mode 100644 src/main/resources/static/raids/vault_of_glass/confluxes/confluxes.jpg create mode 100644 src/main/resources/static/raids/vault_of_glass/gatekeeper/gatekeepers.jpg create mode 100644 src/main/resources/static/raids/vault_of_glass/gatekeeper/venus_mars.jpg create mode 100644 src/main/resources/static/raids/vault_of_glass/gorgons_labrynth/gorgons_labrynth.jpg create mode 100644 src/main/resources/static/raids/vault_of_glass/oracles/oracles.jpg create mode 100644 src/main/resources/static/raids/vault_of_glass/templar/templar.jpg diff --git a/.gitignore b/.gitignore index 9daaf23..25bb938 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ build/ !**/src/test/**/build/ \\ \\.pub +compose.yml ### STS ### .apt_generated diff --git a/build.gradle b/build.gradle index 6d0d5cb..8662eaf 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { } group = 'com.danielvm' -version = '0.1.0-alpha' +version = '0.2.0-alpha' java { diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..6ecba15 --- /dev/null +++ b/compose.yml @@ -0,0 +1,60 @@ +services: + riven-of-a-thousand-servers: + image: ${DOCKER_IMAGE_NAME} + env_file: + - .env + ports: + - "8080:8080" + depends_on: + - redis + - mongodb + secrets: + - mongo_username + - mongo_password + - discord_bot_token + - discord_bot_public_key + - discord_application_id + - discord_client_id + - discord_client_secret + - bungie_api_key + - bungie_client_id + - bungie_client_secret + redis: + hostname: redis + image: "redis:7.0.11" + ports: + - "6379:6379" + mongodb: + hostname: mongo + image: "mongo:7.0.3" + ports: + - "27017:27017" + environment: + MONGO_INITDB_ROOT_USERNAME_FILE: /run/secrets/mongo_username + MONGO_INITDB_ROOT_PASSWORD_FILE: /run/secrets/mongo_password + MONGO_INITDB_DATABASE: riven_of_a_thousand_servers + secrets: + - "mongo_username" + - "mongo_password" + +secrets: + mongo_username: + environment: "MONGO_DB_ROOT_USERNAME" + mongo_password: + environment: "MONGO_DB_ROOT_PASSWORD" + discord_bot_token: + environment: "DISCORD_BOT_TOKEN" + discord_bot_public_key: + environment: "DISCORD_BOT_PUBLIC_KEY" + discord_application_id: + environment: "DISCORD_APPLICATION_ID" + discord_client_id: + environment: "DISCORD_CLIENT_ID" + discord_client_secret: + environment: "DISCORD_CLIENT_SECRET" + bungie_api_key: + environment: "BUNGIE_API_KEY" + bungie_client_id: + environment: "BUNGIE_CLIENT_ID" + bungie_client_secret: + environment: "BUNGIE_CLIENT_SECRET" \ No newline at end of file diff --git a/src/main/java/com/deahtstroke/rivenbot/dto/SocialLink.java b/src/main/java/com/deahtstroke/rivenbot/dto/SocialLink.java new file mode 100644 index 0000000..248c18d --- /dev/null +++ b/src/main/java/com/deahtstroke/rivenbot/dto/SocialLink.java @@ -0,0 +1,23 @@ +package com.deahtstroke.rivenbot.dto; + +import com.deahtstroke.rivenbot.enums.SocialPlatform; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class SocialLink { + + /** + * Social Platform this link belongs to + */ + private SocialPlatform socialPlatform; + + /** + * Social media hyperlink + */ + private String socialLink; + +} diff --git a/src/main/java/com/deahtstroke/rivenbot/dto/discord/Emoji.java b/src/main/java/com/deahtstroke/rivenbot/dto/discord/Emoji.java index 31d6929..44bbb94 100644 --- a/src/main/java/com/deahtstroke/rivenbot/dto/discord/Emoji.java +++ b/src/main/java/com/deahtstroke/rivenbot/dto/discord/Emoji.java @@ -1,12 +1,14 @@ package com.deahtstroke.rivenbot.dto.discord; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor +@Builder public class Emoji { /** diff --git a/src/main/java/com/deahtstroke/rivenbot/enums/Raid.java b/src/main/java/com/deahtstroke/rivenbot/enums/Raid.java index ddea70e..6b07391 100644 --- a/src/main/java/com/deahtstroke/rivenbot/enums/Raid.java +++ b/src/main/java/com/deahtstroke/rivenbot/enums/Raid.java @@ -1,18 +1,25 @@ package com.deahtstroke.rivenbot.enums; +import com.deahtstroke.rivenbot.dto.SocialLink; +import java.util.List; import java.util.Objects; import java.util.stream.Stream; import lombok.Getter; public enum Raid { - LAST_WISH("Last Wish", "last_wish"), - GARDEN_OF_SALVATION("Garden of Salvation", "garden_of_salvation"), - DEEP_STONE_CRYPT("Deep Stone Crypt", "deep_stone_crypt"), - VAULT_OF_GLASS("Vault of Glass", "vault_of_glass"), - VOW_OF_THE_DISCIPLE("Vow of the Disciple", "vow_of_the_disciple"), - KINGS_FALL("King's Fall", "kings_fall"), - ROOT_OF_NIGHTMARES("Root of Nightmares", "root_of_nightmares"), - CROTAS_END("Crota's End", "crotas_end"); + LAST_WISH("Last Wish", "last_wish", + "a-phantom-moon", + List.of( + new SocialLink(SocialPlatform.DEVIANTART, "https://www.deviantart.com/a-phantom-moon"))), + GARDEN_OF_SALVATION("Garden of Salvation", "garden_of_salvation", null, null), + DEEP_STONE_CRYPT("Deep Stone Crypt", "deep_stone_crypt", null, null), + VAULT_OF_GLASS("Vault of Glass", "vault_of_glass", "SCA", + List.of( + new SocialLink(SocialPlatform.STEAM, "https://steamcommunity.com/id/scaro25"))), + VOW_OF_THE_DISCIPLE("Vow of the Disciple", "vow_of_the_disciple", null, null), + KINGS_FALL("King's Fall", "kings_fall", null, null), + ROOT_OF_NIGHTMARES("Root of Nightmares", "root_of_nightmares", null, null), + CROTAS_END("Crota's End", "crotas_end", null, null); @Getter private final String raidName; @@ -20,9 +27,17 @@ public enum Raid { @Getter private final String raidDirectory; - Raid(String raidName, String raidDirectory) { + @Getter + private final String artistName; + + @Getter + private final List artistSocials; + + Raid(String raidName, String raidDirectory, String artistName, List artistSocials) { this.raidName = raidName; this.raidDirectory = raidDirectory; + this.artistName = artistName; + this.artistSocials = artistSocials; } /** diff --git a/src/main/java/com/deahtstroke/rivenbot/enums/SocialPlatform.java b/src/main/java/com/deahtstroke/rivenbot/enums/SocialPlatform.java new file mode 100644 index 0000000..fdd5cef --- /dev/null +++ b/src/main/java/com/deahtstroke/rivenbot/enums/SocialPlatform.java @@ -0,0 +1,24 @@ +package com.deahtstroke.rivenbot.enums; + +import lombok.Getter; + +public enum SocialPlatform { + + DEVIANTART("DeviantArt", ":deviantart:", 1240125288885784616L), + STEAM("Steam", ":steamlogo:", 1240514012215513139L); + + @Getter + private final String platformName; + + @Getter + private final String emojiName; + + @Getter + private final Long emojiId; + + SocialPlatform(String platformName, String emojiName, Long emojiId) { + this.platformName = platformName; + this.emojiName = emojiName; + this.emojiId = emojiId; + } +} diff --git a/src/main/java/com/deahtstroke/rivenbot/exception/ImageProcessingException.java b/src/main/java/com/deahtstroke/rivenbot/exception/ImageRetrievalException.java similarity index 54% rename from src/main/java/com/deahtstroke/rivenbot/exception/ImageProcessingException.java rename to src/main/java/com/deahtstroke/rivenbot/exception/ImageRetrievalException.java index e6f67d2..ff44bcd 100644 --- a/src/main/java/com/deahtstroke/rivenbot/exception/ImageProcessingException.java +++ b/src/main/java/com/deahtstroke/rivenbot/exception/ImageRetrievalException.java @@ -2,9 +2,9 @@ import org.springframework.http.HttpStatus; -public class ImageProcessingException extends BaseException { +public class ImageRetrievalException extends BaseException { - public ImageProcessingException(String message, Throwable throwable) { + public ImageRetrievalException(String message, Throwable throwable) { super(message, HttpStatus.INTERNAL_SERVER_ERROR, throwable); } } diff --git a/src/main/java/com/deahtstroke/rivenbot/handler/InteractionHandler.java b/src/main/java/com/deahtstroke/rivenbot/handler/InteractionHandler.java index 658d0b1..bef3747 100644 --- a/src/main/java/com/deahtstroke/rivenbot/handler/InteractionHandler.java +++ b/src/main/java/com/deahtstroke/rivenbot/handler/InteractionHandler.java @@ -106,12 +106,8 @@ private Mono resolveResponse(Interaction interaction, private Mono>> attachmentsResponse( Interaction interaction, InteractionResponse interactionResponse) { - try { - return raidInfographicsService.retrieveEncounterImages(interaction) - .map(assets -> HttpResponseUtils.filesResponse(interactionResponse, assets)); - } catch (IOException e) { - return Mono.error(new RuntimeException(e)); - } + return raidInfographicsService.retrieveEncounterImages(interaction) + .map(assets -> HttpResponseUtils.filesResponse(interactionResponse, assets)); } } diff --git a/src/main/java/com/deahtstroke/rivenbot/handler/RaidMapHandler.java b/src/main/java/com/deahtstroke/rivenbot/handler/RaidMapHandler.java index d3b4000..dedec6d 100644 --- a/src/main/java/com/deahtstroke/rivenbot/handler/RaidMapHandler.java +++ b/src/main/java/com/deahtstroke/rivenbot/handler/RaidMapHandler.java @@ -4,7 +4,9 @@ import com.deahtstroke.rivenbot.dto.discord.Choice; import com.deahtstroke.rivenbot.dto.discord.Component; import com.deahtstroke.rivenbot.dto.discord.Embedded; +import com.deahtstroke.rivenbot.dto.discord.EmbeddedFooter; import com.deahtstroke.rivenbot.dto.discord.EmbeddedImage; +import com.deahtstroke.rivenbot.dto.discord.Emoji; import com.deahtstroke.rivenbot.dto.discord.Interaction; import com.deahtstroke.rivenbot.dto.discord.InteractionResponse; import com.deahtstroke.rivenbot.dto.discord.InteractionResponseData; @@ -32,8 +34,12 @@ public class RaidMapHandler implements ApplicationCommandSource, AutocompleteSource { private static final String EMBED_BINDING_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; + private static final String EMBED_TITLE = "%s at %s"; private static final String RAID_OPTION_NAME = "raid"; + private static final String EMBED_IMAGE_TYPE = "image"; private static final String ENCOUNTER_OPTION_NAME = "encounter"; + private static final String ARTIST_CREDIT_FOOTER_FORMAT = "Infographics by %s!"; + private static final String SOCIAL_LINK_LABEL_FORMAT = "%s's %s"; private final RaidInfographicsService raidInfographicsService; @@ -57,27 +63,33 @@ private static InteractionResponse formatInteractionResponse( RaidEncounter raidEncounter = RaidEncounter.findEncounter(raid, encounterDirectory); - String embedTitle = """ - Encounter maps for: %s at %s""".formatted(raid.getRaidName(), raidEncounter.getName()); List embeds = attachments.stream() .map(attachment -> Embedded.builder() - .title(embedTitle) + .title(EMBED_TITLE.formatted(raid.getRaidName(), raidEncounter.getName())) .url(EMBED_BINDING_URL) - .type("image") + .type(EMBED_IMAGE_TYPE) .image(EmbeddedImage.builder() .url("attachment://" + attachment.getFilename()) .build()) + .footer(EmbeddedFooter.builder() + .text(ARTIST_CREDIT_FOOTER_FORMAT.formatted(raid.getArtistName())) + .build()) .build()) .toList(); InteractionResponseData data = InteractionResponseData.builder() .components(List.of(Component.builder() .type(1) - .components(List.of(Component.builder() - .label("Infographics by A-Phantom-Moon!") - .type(2) - .style(5) - .url("https://www.deviantart.com/a-phantom-moon") - .build())) + .components(raid.getArtistSocials().stream() + .map(socialLink -> Component.builder() + .type(2) + .style(5) + .url(socialLink.getSocialLink()) + .label(SOCIAL_LINK_LABEL_FORMAT.formatted(raid.getArtistName(), + socialLink.getSocialPlatform().getPlatformName())) + .emoji(new Emoji(socialLink.getSocialPlatform().getEmojiId(), + socialLink.getSocialPlatform().getEmojiName(), false)) + .build()) + .toList()) .build())) .attachments(attachments) .embeds(embeds) @@ -108,19 +120,17 @@ private static List extractAttachments(Map map) { @Override public Mono createResponse(Interaction interaction) { - try { - return raidInfographicsService.retrieveEncounterImages(interaction) - .map(RaidMapHandler::extractAttachments) - .map(attachments -> formatInteractionResponse(interaction, attachments)); - } catch (IOException e) { - String raidName = InteractionUtils.retrieveInteractionOption(interaction.getData() - .getOptions(), ENCOUNTER_OPTION_NAME); - String errorMessage = - "Something wrong happened while retrieving encounter images for raid [%s]".formatted( - raidName); - log.error(errorMessage, e); - throw new InternalServerException(errorMessage, e); - } + return raidInfographicsService.retrieveEncounterImages(interaction) + .map(RaidMapHandler::extractAttachments) + .map(attachments -> formatInteractionResponse(interaction, attachments)) + .onErrorResume(IOException.class, err -> { + String raidName = InteractionUtils.retrieveInteractionOption(interaction.getData() + .getOptions(), ENCOUNTER_OPTION_NAME); + String errorMessage = "Something wrong happened while retrieving encounter images for raid [%s]" + .formatted(raidName); + log.error(errorMessage, err); + return Mono.error(new InternalServerException(errorMessage, err)); + }); } @Override diff --git a/src/main/java/com/deahtstroke/rivenbot/service/RaidInfographicsService.java b/src/main/java/com/deahtstroke/rivenbot/service/RaidInfographicsService.java index 09b49fc..261dce6 100644 --- a/src/main/java/com/deahtstroke/rivenbot/service/RaidInfographicsService.java +++ b/src/main/java/com/deahtstroke/rivenbot/service/RaidInfographicsService.java @@ -2,9 +2,10 @@ import com.deahtstroke.rivenbot.dto.discord.Interaction; import com.deahtstroke.rivenbot.dto.discord.Option; -import com.deahtstroke.rivenbot.exception.ImageProcessingException; +import com.deahtstroke.rivenbot.exception.ImageRetrievalException; import com.deahtstroke.rivenbot.util.InteractionUtils; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Map; import lombok.extern.slf4j.Slf4j; @@ -36,25 +37,24 @@ public RaidInfographicsService(PathMatchingResourcePatternResolver resourcePatte * @return HashMap with an indexed key and a value of the corresponding classpath resource * @throws IOException In case something unexpected happens when retrieving the files in memory */ - public Mono> retrieveEncounterImages(Interaction interaction) - throws IOException { + public Mono> retrieveEncounterImages(Interaction interaction) { List