Skip to content

Commit

Permalink
Hidden roll (#345)
Browse files Browse the repository at this point in the history
* wip

* wip

* wip

* wip

* cleanup and fix tests

* cleanup

* test und doc

* cleanup

* fix test
  • Loading branch information
twonirwana authored Oct 18, 2023
1 parent 774487a commit bbf407a
Show file tree
Hide file tree
Showing 63 changed files with 1,592 additions and 826 deletions.
9 changes: 9 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,15 @@ For example `/r expression:3d6` will simply roll 3d6 and post the result without
The result of the dice will be summed up per default.
The output can be configured with the `channel_config` command.

=== Hidden Direct Roll

image:image/hiddenDircetRoll.webp[image]

With the command `/h` it is possible to directly call the dice expression (see <<Dice Expression Notation>>) like <<Direct Roll>> but the answer is initial only visible to the user and can be revealed to other user by pressing on the button "Reveal".
For example `/h expression:3d6` will simply roll 3d6 and show only the current user the result.
The result of the dice will be summed up per default.
The output can be configured with the `channel_config` command.

=== Channel Config

This command is used create a channel specific configuration.
Expand Down
2 changes: 2 additions & 0 deletions bot/src/main/java/de/janno/discord/bot/Bot.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import de.janno.discord.bot.command.customDice.CustomDiceCommand;
import de.janno.discord.bot.command.customParameter.CustomParameterCommand;
import de.janno.discord.bot.command.directRoll.DirectRollCommand;
import de.janno.discord.bot.command.directRoll.HiddenDirectRollCommand;
import de.janno.discord.bot.command.directRoll.ValidationCommand;
import de.janno.discord.bot.command.fate.FateCommand;
import de.janno.discord.bot.command.help.HelpCommand;
Expand Down Expand Up @@ -73,6 +74,7 @@ public static void main(final String[] args) throws Exception {
customDiceCommand,
fateCommand,
new DirectRollCommand(persistenceManager, cachingDiceEvaluator),
new HiddenDirectRollCommand(persistenceManager, cachingDiceEvaluator),
new ValidationCommand(persistenceManager, cachingDiceEvaluator),
new ChannelConfigCommand(persistenceManager),
new SumDiceSetCommand(persistenceManager),
Expand Down
23 changes: 11 additions & 12 deletions bot/src/main/java/de/janno/discord/bot/command/AbstractCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import de.janno.discord.connector.api.*;
import de.janno.discord.connector.api.message.ComponentRowDefinition;
import de.janno.discord.connector.api.message.EmbedOrMessageDefinition;
import de.janno.discord.connector.api.message.MessageDefinition;
import de.janno.discord.connector.api.slash.CommandDefinition;
import de.janno.discord.connector.api.slash.CommandDefinitionOption;
import de.janno.discord.connector.api.slash.CommandInteractionOption;
Expand Down Expand Up @@ -68,7 +67,7 @@ public boolean matchingComponentCustomId(@NonNull String buttonCustomId) {
if (BottomCustomIdUtils.isLegacyCustomId(buttonCustomId)) {
return BottomCustomIdUtils.matchesLegacyCustomId(buttonCustomId, getCommandId());
}
return Objects.equals(getCommandId(), BottomCustomIdUtils.getCommandNameFromCustomIdWithPersistence(buttonCustomId));
return Objects.equals(getCommandId(), BottomCustomIdUtils.getCommandNameFromCustomId(buttonCustomId));
}

@Override
Expand Down Expand Up @@ -190,7 +189,7 @@ public Mono<Void> handleComponentInteractEvent(@NonNull ButtonEventAdaptor event
return event.reply("The button uses an old format that isn't supported anymore. Please delete it and create a new button message with a slash command.", false);
} else {
final String buttonValue = BottomCustomIdUtils.getButtonValueFromCustomId(event.getCustomId());
final Optional<UUID> configUUIDFromCustomID = BottomCustomIdUtils.getConfigUUIDFromCustomIdWithPersistence(event.getCustomId());
final Optional<UUID> configUUIDFromCustomID = BottomCustomIdUtils.getConfigUUIDFromCustomId(event.getCustomId());
BotMetrics.incrementButtonUUIDUsageMetricCounter(getCommandId(), configUUIDFromCustomID.isPresent());
final Optional<MessageConfigDTO> messageConfigDTO = getMessageConfigDTO(configUUIDFromCustomID.orElse(null), channelId, messageId);
if (messageConfigDTO.isEmpty()) {
Expand All @@ -217,8 +216,8 @@ public Mono<Void> handleComponentInteractEvent(@NonNull ButtonEventAdaptor event
Optional<List<ComponentRowDefinition>> editMessageComponents;
if (keepExistingButtonMessage || answerTargetChannelId != null) {
//if the old button is pined or the result is copied to another channel, the old message will be edited or reset to the slash default
editMessage = getCurrentMessageContentChange(config, state).orElse(createNewButtonMessage(configUUID, config).getContent());
editMessageComponents = Optional.ofNullable(getCurrentMessageComponentChange(configUUID, config, state, channelId, userId)
editMessage = getCurrentMessageContentChange(config, state).orElse(createNewButtonMessage(configUUID, config).getDescriptionOrContent());
editMessageComponents = Optional.of(getCurrentMessageComponentChange(configUUID, config, state, channelId, userId)
.orElse(createNewButtonMessage(configUUID, config).getComponentRowDefinitions()));
} else {
//edit the current message if the command changes it or mark it as processing
Expand All @@ -234,7 +233,7 @@ public Mono<Void> handleComponentInteractEvent(@NonNull ButtonEventAdaptor event
BotMetrics.incrementButtonMetricCounter(getCommandId(), config.toShortString());
BotMetrics.incrementAnswerFormatCounter(config.getAnswerFormatType(), getCommandId());

actions.add(Mono.defer(() -> event.createResultMessageWithEventReference(RollAnswerConverter.toEmbedOrMessageDefinition(answer.get()), answerTargetChannelId)
actions.add(Mono.defer(() -> event.createResultMessageWithReference(RollAnswerConverter.toEmbedOrMessageDefinition(answer.get()), answerTargetChannelId)
.doOnSuccess(v -> {
BotMetrics.timerAnswerMetricCounter(getCommandId(), stopwatch.elapsed());
log.info("{}: '{}'={} -> {} in {}ms",
Expand All @@ -247,11 +246,11 @@ public Mono<Void> handleComponentInteractEvent(@NonNull ButtonEventAdaptor event
})));

}
Optional<MessageDefinition> newButtonMessage = createNewButtonMessageWithState(configUUID, config, state, guildId, channelId);
Optional<EmbedOrMessageDefinition> newButtonMessage = createNewButtonMessageWithState(configUUID, config, state, guildId, channelId);

final boolean deleteCurrentButtonMessage;
if (newButtonMessage.isPresent() && answerTargetChannelId == null) {
actions.add(Mono.defer(() -> event.createButtonMessage(newButtonMessage.get()))
actions.add(Mono.defer(() -> event.createMessageWithoutReference(newButtonMessage.get()))
.doOnNext(newMessageId -> createEmptyMessageData(configUUID, guildId, channelId, newMessageId))
.flatMap(newMessageId -> deleteOldAndConcurrentMessageAndData(newMessageId, configUUID, channelId, event))
.delaySubscription(calculateDelay(event))
Expand Down Expand Up @@ -386,14 +385,14 @@ Mono<Void> deleteOldAndConcurrentMessageAndData(
.then(Mono.defer(() -> {
final Optional<MessageConfigDTO> newMessageConfig = createMessageConfig(configUUID, guildId, channelId, config);
newMessageConfig.ifPresent(persistenceManager::saveMessageConfig);
return event.createButtonMessage(createNewButtonMessage(configUUID, config))
return event.createMessageWithoutReference(createNewButtonMessage(configUUID, config))
.doOnNext(messageId -> createEmptyMessageData(configUUID, guildId, channelId, messageId))
.then();
}));

} else if (event.getOption(ACTION_HELP).isPresent()) {
BotMetrics.incrementSlashHelpMetricCounter(getCommandId());
return event.replyEmbed(getHelpMessage(), true);
return event.replyWithEmbedOrMessageDefinition(getHelpMessage(), true);
}
return Mono.empty();
}
Expand Down Expand Up @@ -421,14 +420,14 @@ Mono<Void> deleteOldAndConcurrentMessageAndData(
/**
* The new button message, after a button event
*/
protected abstract @NonNull Optional<MessageDefinition> createNewButtonMessageWithState(UUID configId, C config, State<S> state, long guildId, long channelId);
protected abstract @NonNull Optional<EmbedOrMessageDefinition> createNewButtonMessageWithState(UUID configId, C config, State<S> state, long guildId, long channelId);

protected abstract @NonNull Optional<RollAnswer> getAnswer(C config, State<S> state, long channelId, long userId);

/**
* The new button message, after a slash event
*/
public abstract @NonNull MessageDefinition createNewButtonMessage(UUID configId, C config);
public abstract @NonNull EmbedOrMessageDefinition createNewButtonMessage(UUID configId, C config);

protected @NonNull Optional<String> getStartOptionsValidationMessage(@NonNull CommandInteractionOption options, long channelId, long userId) {
//standard is no validation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import de.janno.discord.connector.api.message.ButtonDefinition;
import de.janno.discord.connector.api.message.ComponentRowDefinition;
import de.janno.discord.connector.api.message.EmbedOrMessageDefinition;
import de.janno.discord.connector.api.message.MessageDefinition;
import de.janno.discord.connector.api.slash.CommandDefinitionOption;
import de.janno.discord.connector.api.slash.CommandDefinitionOptionChoice;
import de.janno.discord.connector.api.slash.CommandInteractionOption;
Expand Down Expand Up @@ -230,7 +229,7 @@ protected boolean supportsResultImages() {
}

@Override
protected @NonNull Optional<MessageDefinition> createNewButtonMessageWithState(UUID configUUID, CountSuccessesConfig config, State<StateData> state, long guildId, long channelId) {
protected @NonNull Optional<EmbedOrMessageDefinition> createNewButtonMessageWithState(UUID configUUID, CountSuccessesConfig config, State<StateData> state, long guildId, long channelId) {
return Optional.of(createNewButtonMessage(configUUID, config));
}

Expand All @@ -243,10 +242,11 @@ private String getBotchDescription(CountSuccessesConfig config) {
}

@Override
public @NonNull MessageDefinition createNewButtonMessage(UUID configUUID, CountSuccessesConfig config) {
public @NonNull EmbedOrMessageDefinition createNewButtonMessage(UUID configUUID, CountSuccessesConfig config) {

return MessageDefinition.builder()
.content(String.format("Click to roll the dice against %s%s%s%s", config.getTarget(), getRerollDescription(config), getBotchDescription(config), getGlitchDescription(config)))
return EmbedOrMessageDefinition.builder()
.type(EmbedOrMessageDefinition.Type.MESSAGE)
.descriptionOrContent(String.format("Click to roll the dice against %s%s%s%s", config.getTarget(), getRerollDescription(config), getBotchDescription(config), getGlitchDescription(config)))
.componentRowDefinitions(createButtonLayout(configUUID, config))
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import de.janno.discord.connector.api.message.ButtonDefinition;
import de.janno.discord.connector.api.message.ComponentRowDefinition;
import de.janno.discord.connector.api.message.EmbedOrMessageDefinition;
import de.janno.discord.connector.api.message.MessageDefinition;
import de.janno.discord.connector.api.slash.CommandDefinitionOption;
import de.janno.discord.connector.api.slash.CommandInteractionOption;
import lombok.NonNull;
Expand Down Expand Up @@ -180,14 +179,15 @@ CustomDiceConfig getConfigOptionStringList(List<ButtonIdAndExpression> startOpti
}

@Override
protected @NonNull Optional<MessageDefinition> createNewButtonMessageWithState(UUID configUUID, CustomDiceConfig config, State<StateData> state, long guildId, long channelId) {
protected @NonNull Optional<EmbedOrMessageDefinition> createNewButtonMessageWithState(UUID configUUID, CustomDiceConfig config, State<StateData> state, long guildId, long channelId) {
return Optional.of(createNewButtonMessage(configUUID, config));
}

@Override
public @NonNull MessageDefinition createNewButtonMessage(UUID configUUID, CustomDiceConfig config) {
return MessageDefinition.builder()
.content(BUTTON_MESSAGE)
public @NonNull EmbedOrMessageDefinition createNewButtonMessage(UUID configUUID, CustomDiceConfig config) {
return EmbedOrMessageDefinition.builder()
.type(EmbedOrMessageDefinition.Type.MESSAGE)
.descriptionOrContent(BUTTON_MESSAGE)
.componentRowDefinitions(createButtonLayout(configUUID, config))
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import de.janno.discord.connector.api.message.ButtonDefinition;
import de.janno.discord.connector.api.message.ComponentRowDefinition;
import de.janno.discord.connector.api.message.EmbedOrMessageDefinition;
import de.janno.discord.connector.api.message.MessageDefinition;
import de.janno.discord.connector.api.slash.CommandDefinitionOption;
import de.janno.discord.connector.api.slash.CommandInteractionOption;
import lombok.NonNull;
Expand Down Expand Up @@ -320,9 +319,10 @@ protected AnswerFormatType defaultAnswerFormat() {
}

@Override
public @NonNull MessageDefinition createNewButtonMessage(UUID configUUID, CustomParameterConfig config) {
return MessageDefinition.builder()
.content(formatMessageContent(config, null, null))
public @NonNull EmbedOrMessageDefinition createNewButtonMessage(UUID configUUID, CustomParameterConfig config) {
return EmbedOrMessageDefinition.builder()
.type(EmbedOrMessageDefinition.Type.MESSAGE)
.descriptionOrContent(formatMessageContent(config, null, null))
.componentRowDefinitions(getButtonLayoutWithOptionalState(configUUID, config, null))
.build();
}
Expand Down Expand Up @@ -404,10 +404,10 @@ protected void updateCurrentMessageStateData(UUID configUUID, long guildId, long
}

@Override
protected @NonNull Optional<MessageDefinition> createNewButtonMessageWithState(UUID configUUID, CustomParameterConfig config, State<CustomParameterStateData> state, long guildId, long channelId) {
protected @NonNull Optional<EmbedOrMessageDefinition> createNewButtonMessageWithState(UUID configUUID, CustomParameterConfig config, State<CustomParameterStateData> state, long guildId, long channelId) {
if (!hasMissingParameter(state)) {
return Optional.of(MessageDefinition.builder()
.content(formatMessageContent(config, state, null))
return Optional.of(EmbedOrMessageDefinition.builder()
.descriptionOrContent(formatMessageContent(config, state, null))
.componentRowDefinitions(getButtonLayoutWithOptionalState(configUUID, config, null))
.build());
}
Expand Down
Loading

0 comments on commit bbf407a

Please sign in to comment.