Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added raid maps for all encounters in Vault of Glass #93

Merged
merged 2 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ build/
!**/src/test/**/build/
\\
\\.pub
compose.yml

### STS ###
.apt_generated
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

group = 'com.danielvm'
version = '0.1.0-alpha'
version = '0.2.0-alpha'


java {
Expand Down
60 changes: 60 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
@@ -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"
23 changes: 23 additions & 0 deletions src/main/java/com/deahtstroke/rivenbot/dto/SocialLink.java
Original file line number Diff line number Diff line change
@@ -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;

}
2 changes: 2 additions & 0 deletions src/main/java/com/deahtstroke/rivenbot/dto/discord/Emoji.java
Original file line number Diff line number Diff line change
@@ -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 {

/**
Expand Down
33 changes: 24 additions & 9 deletions src/main/java/com/deahtstroke/rivenbot/enums/Raid.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
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;

@Getter
private final String raidDirectory;

Raid(String raidName, String raidDirectory) {
@Getter
private final String artistName;

@Getter
private final List<SocialLink> artistSocials;

Raid(String raidName, String raidDirectory, String artistName, List<SocialLink> artistSocials) {
this.raidName = raidName;
this.raidDirectory = raidDirectory;
this.artistName = artistName;
this.artistSocials = artistSocials;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public enum RaidEncounter {
TANIKS_THE_ABOMNITAION(Raid.DEEP_STONE_CRYPT, "Taniks, the Abomination", "taniks_the_abomination"),

// Vault of Glass
OPEN_THE_VAULT(Raid.VAULT_OF_GLASS, "Opening the Vault", "the_vault"),
CONFLUXES(Raid.VAULT_OF_GLASS, "Confluxes", "confluxes"),
ORACLES(Raid.VAULT_OF_GLASS, "Oracles", "oracles"),
THE_TEMPLAR(Raid.VAULT_OF_GLASS, "The Templar", "templar"),
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/com/deahtstroke/rivenbot/enums/SocialPlatform.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,8 @@ private Mono<InteractionResponse> resolveResponse(Interaction interaction,

private Mono<MultiValueMap<String, HttpEntity<?>>> 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));
}

}
56 changes: 33 additions & 23 deletions src/main/java/com/deahtstroke/rivenbot/handler/RaidMapHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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<Embedded> 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)
Expand Down Expand Up @@ -108,19 +120,17 @@ private static List<Attachment> extractAttachments(Map<Long, Resource> map) {

@Override
public Mono<InteractionResponse> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -36,25 +37,26 @@ 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<Map<Long, Resource>> retrieveEncounterImages(Interaction interaction)
throws IOException {
public Mono<Map<Long, Resource>> retrieveEncounterImages(Interaction interaction) {
List<Option> options = interaction.getData().getOptions();
String raidDirectory = InteractionUtils.retrieveInteractionOption(options, RAID_OPTION_NAME);
String encounterDirectory = InteractionUtils.retrieveInteractionOption(options, ENCOUNTER_OPTION_NAME);
String encounterDirectory = InteractionUtils.retrieveInteractionOption(options,
ENCOUNTER_OPTION_NAME);

String basePath = ASSETS_BASE_PATH.formatted(raidDirectory, encounterDirectory);
Resource[] resources;
try {
resources = resourcePatternResolver.getResources(basePath);
} catch (IOException e) {
log.error("Something unexpected happened when fetching [{}]", basePath, e);
throw new ImageProcessingException(
"Something unexpected happened when fetching resources for raid [%s] and encounter [%s]".formatted(
raidDirectory, encounterDirectory), e);
}
return Flux.fromArray(resources)
.index()
.collectMap(Tuple2::getT1, Tuple2::getT2);
return Mono.defer(() -> {
try {
Resource[] resources = resourcePatternResolver.getResources(basePath);
return Flux.fromIterable(Arrays.asList(resources))
.index()
.collectMap(Tuple2::getT1, Tuple2::getT2);
} catch (IOException e) {
log.error("There was an error retrieving images for raid [{}] at encounter [{}]",
raidDirectory, encounterDirectory);
return Mono.error(new ImageRetrievalException(
"Something unexpected happened when fetching resources for raid [%s] and encounter [%s]"
.formatted(raidDirectory, encounterDirectory), e));
}
});
}

}
Loading
Loading