Skip to content

Commit

Permalink
Add more instances in which Dadbot can reply (#1054)
Browse files Browse the repository at this point in the history
Closes #936
  • Loading branch information
Nincodedo authored Nov 1, 2024
1 parent 9bff3d6 commit 7f458e6
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
import dev.nincodedo.nincord.config.db.component.ComponentService;
import dev.nincodedo.nincord.message.MessageExecutor;
import dev.nincodedo.nincord.message.MessageReceivedEventMessageExecutor;
import dev.nincodedo.nincord.message.MessageUtils;
import dev.nincodedo.nincord.message.impersonation.Impersonation;
import dev.nincodedo.nincord.stats.StatManager;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.WordUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

Expand All @@ -33,6 +31,7 @@ public class Dadbot extends StatAwareListenerAdapter {
private ConfigService configService;
private ComponentService componentService;
private String componentName;
private DadbotMessageParser dadbotMessageParser;
private ResourceBundle resourceBundle = ResourceBundle.getBundle("lang", Locale.ENGLISH);
private Impersonation dadbotImpersonation;

Expand All @@ -43,6 +42,7 @@ public Dadbot(StatManager statManager, @Qualifier("statCounterThreadPool") Execu
this.configService = configService;
componentName = "dad";
this.componentService = componentService;
this.dadbotMessageParser = new DadbotMessageParser();
this.dadbotImpersonation = Impersonation.of("Dadbot", "https://i.imgur.com/zfKodNp.png");
}

Expand All @@ -58,14 +58,13 @@ public void onMessageReceived(MessageReceivedEvent event) {
private MessageExecutor parseMessage(MessageReceivedEvent event) {
var messageExecutor = new MessageReceivedEventMessageExecutor(event);
var strippedMessage = event.getMessage().getContentStripped();
var first = strippedMessage.split("\\s+")[0];
if (!(first.equalsIgnoreCase(resourceBundle.getString("listener.dad.imcontraction"))
|| first.equalsIgnoreCase(resourceBundle.getString("listener.dad.imnocontraction")))
|| !event.getChannelType().isGuild()) {
var rawMessage = event.getMessage().getContentRaw();
var optionalDadJoke = dadbotMessageParser.dadReply(strippedMessage, rawMessage);
if (optionalDadJoke.isEmpty() || !event.getChannelType().isGuild()) {
return messageExecutor;
}
if (StringUtils.isNotBlank(strippedMessage) && strippedMessage.split("\\s+").length >= 1 && checkChance()) {
hiImDad(event.getMessage(), event, messageExecutor);
if (checkChance()) {
hiImDad(event, messageExecutor, optionalDadJoke.get());
}
return messageExecutor;
}
Expand All @@ -75,32 +74,30 @@ private boolean channelIsOnDenyList(String guildId, String channelId) {
return channelConfigList.stream().anyMatch(config -> config.getValue().equals(channelId));
}

private void hiImDad(Message message, MessageReceivedEvent event,
MessageReceivedEventMessageExecutor messageExecutor) {
private void hiImDad(MessageReceivedEvent event,
MessageReceivedEventMessageExecutor messageExecutor, String dadName) {
if (channelIsOnDenyList(event.getGuild().getId(), event.getChannel().getId())) {
return;
}
messageExecutor.impersonate(dadbotImpersonation);
String strippedMessage = message.getContentStripped();

String dadName = MessageUtils.addSpoilerText(strippedMessage.substring(strippedMessage.indexOf(' '))
.trim(), message.getContentRaw());
String dadResponse = resourceBundle.getString("listener.dad.hi") + " "
+ dadName
+ resourceBundle.getString("listener.dad.imdad");
String dadResponse = String.format(resourceBundle.getString("listener.dad.joke"), dadName);
messageExecutor.addMessageResponse(dadResponse);
dadJoke(dadName, message.getMember());
dadJoke(dadName, event.getMember());
countOneStat(componentName, event.getGuild().getId());
}

private void dadJoke(String dadName, Member member) {
if (dadName.length() > DISCORD_NICKNAME_LENGTH_LIMIT || member == null) {
return;
}
var self = member.getGuild().getSelfMember();
if (dadName.length() > DISCORD_NICKNAME_LENGTH_LIMIT || !self.hasPermission(Permission.NICKNAME_MANAGE)
if (!self.hasPermission(Permission.NICKNAME_MANAGE)
|| !self.canInteract(member)) {
return;
}
var oldName = member.getNickname();
member.modifyNickname(StringUtils.capitalize(dadName))
member.modifyNickname(WordUtils.capitalizeFully(dadName))
.reason("Dad joke")
.queue(success -> member.modifyNickname(oldName)
.reason("Dad joke done")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.nincodedo.ninbot.components.dad;

import dev.nincodedo.nincord.message.MessageUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.Optional;
import java.util.regex.Pattern;

@Slf4j
public class DadbotMessageParser {

public Optional<String> dadReply(String message, String rawMessage) {
var initialPattern = Pattern.compile("i(?:['‛’‵‘′`]?m| am) ", Pattern.CASE_INSENSITIVE);
var initialMatcher = initialPattern.matcher(message);
if (!initialMatcher.find()) {
log.debug("Failed initial matching \"{}\"", message);
return Optional.empty();
}
var startingMessage = message.substring(initialMatcher.end());
var endingPunctuationPattern = Pattern.compile("(?<!Mrs?|M[sx]|[SJD]r)[.?!](:? )?");
var matcher = endingPunctuationPattern.matcher(startingMessage);
if (matcher.find()) {
startingMessage = startingMessage.substring(0, matcher.start());
}

if (!startingMessage.isEmpty()) {
return Optional.of(MessageUtils.addSpoilerText(startingMessage, rawMessage));
} else {
return Optional.empty();
}
}
}
5 changes: 1 addition & 4 deletions ninbot-app/src/main/resources/lang_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ listener.topic.updated.withpermission=%s updated topic to %s
listener.topic.update.nopermission=Topic updated to %s
listener.stream.announce=%s is streaming %s! Check them out at %s
listener.stream.announce.voicechannel=%s is streaming! Check them out at #%s
listener.dad.imcontraction=I'm
listener.dad.imnocontraction=im
listener.dad.hi=Hi
listener.dad.imdad=, I'm Dad!
#Countdowns
countdown.announce.message.tomorrow=Countdown event %s is tomorrow\!
countdown.announce.message.today=Countdown event %s is today\!
Expand Down Expand Up @@ -91,3 +87,4 @@ common.off=off
command.tally.description=Count something, I dunno
listener.stream.announce.banner.footer=How did Ninbot do with this generated banner? Leave some feedback with the buttons below!
listener.goodnumbers.total=All the numbers in your message added up to %d.
listener.dad.joke=Hi %s, I'm Dad!
5 changes: 1 addition & 4 deletions ninbot-app/src/main/resources/lang_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ listener.topic.updated.withpermission=%s updated topic to %s
listener.topic.update.nopermission=Topic updated to %s
listener.stream.announce=%s is streaming %s! Check them out at %s
listener.stream.announce.voicechannel=%s is streaming! Check them out at #%s
listener.dad.imcontraction=I'm
listener.dad.imnocontraction=im
listener.dad.hi=Hi
listener.dad.imdad=, I'm Dad!
#Countdowns
countdown.announce.message.tomorrow=Countdown event %s is tomorrow!
countdown.announce.message.today=Countdown event %s is today!
Expand Down Expand Up @@ -91,3 +87,4 @@ common.off=off
command.tally.description=Count something, I dunno
listener.stream.announce.banner.footer=How did Ninbot do with this generated banner? Leave some feedback with the buttons below!
listener.goodnumbers.total=All the numbers in your message added up to %d.
listener.dad.joke=Hi %s, I'm Dad!
5 changes: 1 addition & 4 deletions ninbot-app/src/main/resources/lang_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ listener.topic.updated.withpermission=%s updated topic to %s
listener.topic.update.nopermission=Topic updated to %s
listener.stream.announce=%s is streaming %s! Check them out at %s
listener.stream.announce.voicechannel=%s is streaming! Check them out at #%s
listener.dad.imcontraction=I'm
listener.dad.imnocontraction=im
listener.dad.hi=Hi
listener.dad.imdad=, I'm Dad!
#Countdowns
countdown.announce.message.tomorrow=Countdown event %s is tomorrow\!
countdown.announce.message.today=Countdown event %s is today\!
Expand Down Expand Up @@ -91,3 +87,4 @@ common.off=off
command.tally.description=Count something, I dunno
listener.stream.announce.banner.footer=How did Ninbot do with this generated banner? Leave some feedback with the buttons below!
listener.goodnumbers.total=All the numbers in your message added up to %d.
listener.dad.joke=Hi %s, I'm Dad!
5 changes: 1 addition & 4 deletions ninbot-app/src/main/resources/lang_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ listener.topic.updated.withpermission=%s updated topic to %s
listener.topic.update.nopermission=Topic updated to %s
listener.stream.announce=%s is streaming %s! Check them out at %s
listener.stream.announce.voicechannel=%s is streaming! Check them out at #%s
listener.dad.imcontraction=I'm
listener.dad.imnocontraction=im
listener.dad.hi=Hi
listener.dad.imdad=, I'm Dad!
#Countdowns
countdown.announce.message.tomorrow=Countdown event %s is tomorrow\!
countdown.announce.message.today=Countdown event %s is today\!
Expand Down Expand Up @@ -91,3 +87,4 @@ common.off=off
command.tally.description=Count something, I dunno
listener.stream.announce.banner.footer=How did Ninbot do with this generated banner? Leave some feedback with the buttons below!
listener.goodnumbers.total=All the numbers in your message added up to %d.n
listener.dad.joke=Hi %s, I'm Dad!
5 changes: 1 addition & 4 deletions ninbot-app/src/main/resources/lang_it.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ listener.topic.updated.withpermission=%s updated topic to %s
listener.topic.update.nopermission=Topic updated to %s
listener.stream.announce=%s is streaming %s! Check them out at %s
listener.stream.announce.voicechannel=%s is streaming! Check them out at #%s
listener.dad.imcontraction=I'm
listener.dad.imnocontraction=im
listener.dad.hi=Hi
listener.dad.imdad=, I'm Dad!
#Countdowns
countdown.announce.message.tomorrow=Countdown event %s is tomorrow\!
countdown.announce.message.today=Countdown event %s is today\!
Expand Down Expand Up @@ -91,3 +87,4 @@ common.off=off
command.tally.description=Count something, I dunno
listener.stream.announce.banner.footer=How did Ninbot do with this generated banner? Leave some feedback with the buttons below!
listener.goodnumbers.total=All the numbers in your message added up to %d.
listener.dad.joke=Hi %s, I'm Dad!
6 changes: 2 additions & 4 deletions ninbot-app/src/main/resources/lang_pt.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ listener.topic.updated.withpermission=%s updated topic to %s
listener.topic.update.nopermission=Topic updated to %s
listener.stream.announce=%s is streaming %s! Check them out at %s
listener.stream.announce.voicechannel=%s is streaming! Check them out at #%s
listener.dad.imcontraction=I'm
listener.dad.imnocontraction=im
listener.dad.hi=Hi
listener.dad.imdad=, I'm Dad!
#Countdowns
countdown.announce.message.tomorrow=Countdown event %s is tomorrow\!
countdown.announce.message.today=Countdown event %s is today\!
Expand Down Expand Up @@ -91,3 +87,5 @@ common.off=off
command.tally.description=Count something, I dunno
listener.stream.announce.banner.footer=How did Ninbot do with this generated banner? Leave some feedback with the buttons below!
listener.goodnumbers.total=All the numbers in your message added up to %d.
listener.dad.joke=Hi %s, I'm Dad!
listener.dad.hi=Hi
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package dev.nincodedo.ninbot.components.dad;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@Slf4j
class DadbotMessageParserTest {

DadbotMessageParser dadbotMessageParser = new DadbotMessageParser();

public static List<String> dadreplies() {
return List.of("I'm happy", "im glad", "i'm tired", "hi im sad", "I'm ready for anything", "I'm a really long"
+ " message with another sentence in it. This should still reply correctly.",
"This is also a really long message with another sentence in it, but the dad part doesn't happen "
+ "until later. I'm sure it will still work.", "I'm this, and this.", "I'm Dr. Mario and "
+ "this is my favorite Discord server.",
"""
Long ago in a distant land, I Aku unleashed an unspeakable evil.
It was a multiline string.
I'm sure this is fine.
""", "I'm using more punctuation than required!!!", "I'm saying I'm multiple times and that's"
+ " normal I'm sure.", "the beginning of this sentence doesn't have anything good in it but "
+ "I'm sure in the end it will.");
}

public static List<String> nodadreplies() {
return List.of("I'm", "I'm ", "Just words that don't have that word");
}

@ParameterizedTest
@MethodSource("dadreplies")
void dadReply(String message) {
var actual = dadbotMessageParser.dadReply(message, "");
assertThat(actual).isPresent();
log.debug(actual.get());
}

@ParameterizedTest
@MethodSource("nodadreplies")
void noDadReply(String message) {
var actual = dadbotMessageParser.dadReply(message, "");
assertThat(actual).isEmpty();
}
}

0 comments on commit 7f458e6

Please sign in to comment.