Compare commits
54 Commits
renovate/o
...
0762068465
| Author | SHA1 | Date | |
|---|---|---|---|
| 0762068465 | |||
| cc9aee3441 | |||
| 86c7c30d8f | |||
| 19e3cde7e6 | |||
| 72f9bb4eb5 | |||
| 407ca279f5 | |||
| 9eefa4b958 | |||
| 9278b485d9 | |||
| 5a2205e567 | |||
| 3212ceb03c | |||
| a80b2cc5a9 | |||
| d087de1d01 | |||
| 99fc980e00 | |||
| 02627ab732 | |||
| dead16f338 | |||
| 2f51f9d40c | |||
| 5f5fc8d3a8 | |||
| 4c98182da7 | |||
| 9e57a3a426 | |||
| 2bf08c27b7 | |||
| b085efeccb | |||
| d8604c7ae5 | |||
| e83d7de7f5 | |||
| dfa25e54f3 | |||
| d1dc71dde9 | |||
| 6fcd3b4cdf | |||
| deb7d83e64 | |||
| 010a25fd66 | |||
| 7c2530c88b | |||
| 20665f4862 | |||
| ecfa3cded8 | |||
| 90e0c4ddf9 | |||
| fd9fe4ead6 | |||
| 6cdd44da29 | |||
| 3dd30a3a89 | |||
| 5c8bad2b02 | |||
| b23bc30fc0 | |||
| 018e24034f | |||
|
|
1a19a9ea06 | ||
|
|
495f164552 | ||
|
|
fd100649a7 | ||
|
|
b3990ff04f | ||
|
|
f5238ced89 | ||
|
|
f0ee565185 | ||
|
|
a21d179308 | ||
|
|
36ad728bbc | ||
|
|
1a6fe6465c | ||
|
|
f0004dc555 | ||
|
|
8ddf0ab80d | ||
|
|
660e18d1f4 | ||
|
|
db943f7e05 | ||
|
|
cb49bda84a | ||
|
|
b318b9f22b | ||
|
|
1447f8c177 |
19
pom.xml
19
pom.xml
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>wtf.beatrice.hidekobot</groupId>
|
<groupId>wtf.beatrice.hidekobot</groupId>
|
||||||
<artifactId>HidekoBot</artifactId>
|
<artifactId>HidekoBot</artifactId>
|
||||||
<version>0.5.0</version>
|
<version>0.5.9</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>16</maven.compiler.source>
|
<maven.compiler.source>16</maven.compiler.source>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.dv8tion</groupId>
|
<groupId>net.dv8tion</groupId>
|
||||||
<artifactId>JDA</artifactId>
|
<artifactId>JDA</artifactId>
|
||||||
<version>5.0.0-alpha.22</version>
|
<version>5.0.0-beta.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
@@ -40,6 +40,21 @@
|
|||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>1.33</version>
|
<version>1.33</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jsoup</groupId>
|
||||||
|
<artifactId>jsoup</artifactId>
|
||||||
|
<version>1.15.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-text</artifactId>
|
||||||
|
<version>1.10.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.vdurmont</groupId>
|
||||||
|
<artifactId>emoji-java</artifactId>
|
||||||
|
<version>5.1.1</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import wtf.beatrice.hidekobot.listeners.SlashCommandCompletionListener;
|
|||||||
import wtf.beatrice.hidekobot.listeners.SlashCommandListener;
|
import wtf.beatrice.hidekobot.listeners.SlashCommandListener;
|
||||||
import wtf.beatrice.hidekobot.runnables.ExpiredMessageTask;
|
import wtf.beatrice.hidekobot.runnables.ExpiredMessageTask;
|
||||||
import wtf.beatrice.hidekobot.runnables.HeartBeatTask;
|
import wtf.beatrice.hidekobot.runnables.HeartBeatTask;
|
||||||
|
import wtf.beatrice.hidekobot.util.CommandUtil;
|
||||||
import wtf.beatrice.hidekobot.util.Logger;
|
import wtf.beatrice.hidekobot.util.Logger;
|
||||||
import wtf.beatrice.hidekobot.util.SlashCommandUtil;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -121,18 +121,28 @@ public class HidekoBot
|
|||||||
slashCommandListener.registerCommand(new DieCommand());
|
slashCommandListener.registerCommand(new DieCommand());
|
||||||
slashCommandListener.registerCommand(new HelpCommand());
|
slashCommandListener.registerCommand(new HelpCommand());
|
||||||
slashCommandListener.registerCommand(new InviteCommand());
|
slashCommandListener.registerCommand(new InviteCommand());
|
||||||
|
slashCommandListener.registerCommand(new MagicBallCommand());
|
||||||
slashCommandListener.registerCommand(new PingCommand());
|
slashCommandListener.registerCommand(new PingCommand());
|
||||||
slashCommandListener.registerCommand(new SayCommand());
|
slashCommandListener.registerCommand(new SayCommand());
|
||||||
|
slashCommandListener.registerCommand(new UrbanDictionaryCommand());
|
||||||
Cache.setSlashCommandListener(slashCommandListener);
|
Cache.setSlashCommandListener(slashCommandListener);
|
||||||
Cache.setSlashCommandCompletionListener(slashCommandCompletionListener);
|
Cache.setSlashCommandCompletionListener(slashCommandCompletionListener);
|
||||||
|
|
||||||
// register message commands
|
// register message commands
|
||||||
MessageCommandListener messageCommandListener = new MessageCommandListener();
|
MessageCommandListener messageCommandListener = new MessageCommandListener();
|
||||||
messageCommandListener.registerCommand(new HelloCommand());
|
messageCommandListener.registerCommand(new HelloCommand());
|
||||||
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.InviteCommand());
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.AliasCommand());
|
||||||
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.AvatarCommand());
|
||||||
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.BotInfoCommand());
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.BotInfoCommand());
|
||||||
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.CoinFlipCommand());
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.CoinFlipCommand());
|
||||||
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.ClearCommand());
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.ClearCommand());
|
||||||
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.DiceRollCommand());
|
||||||
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.HelpCommand());
|
||||||
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.InviteCommand());
|
||||||
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.LoveCalculatorCommand());
|
||||||
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.MagicBallCommand());
|
||||||
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.SayCommand());
|
||||||
|
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.UrbanDictionaryCommand());
|
||||||
Cache.setMessageCommandListener(messageCommandListener);
|
Cache.setMessageCommandListener(messageCommandListener);
|
||||||
|
|
||||||
// register listeners
|
// register listeners
|
||||||
@@ -144,7 +154,7 @@ public class HidekoBot
|
|||||||
// update slash commands (delayed)
|
// update slash commands (delayed)
|
||||||
final boolean finalForceUpdateCommands = forceUpdateCommands;
|
final boolean finalForceUpdateCommands = forceUpdateCommands;
|
||||||
Executors.newSingleThreadScheduledExecutor().schedule(() -> // todo: try-with-resources
|
Executors.newSingleThreadScheduledExecutor().schedule(() -> // todo: try-with-resources
|
||||||
SlashCommandUtil.updateSlashCommands(finalForceUpdateCommands), 1, TimeUnit.SECONDS);
|
CommandUtil.updateSlashCommands(finalForceUpdateCommands), 1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// set the bot's status
|
// set the bot's status
|
||||||
jda.getPresence().setStatus(OnlineStatus.ONLINE);
|
jda.getPresence().setStatus(OnlineStatus.ONLINE);
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.base;
|
||||||
|
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class Alias
|
||||||
|
{
|
||||||
|
public static String generateNiceAliases(MessageCommand command)
|
||||||
|
{
|
||||||
|
LinkedList<String> aliases = command.getCommandLabels();
|
||||||
|
StringBuilder aliasesStringBuilder = new StringBuilder();
|
||||||
|
for(int i = 0; i < aliases.size(); i++)
|
||||||
|
{
|
||||||
|
aliasesStringBuilder.append("`").append(aliases.get(i)).append("`");
|
||||||
|
|
||||||
|
if(i + 1 != aliases.size())
|
||||||
|
aliasesStringBuilder.append(", "); // separate with comma except on last iteration
|
||||||
|
}
|
||||||
|
|
||||||
|
return aliasesStringBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.base;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
|
||||||
|
public class Avatar
|
||||||
|
{
|
||||||
|
public static int parseResolution(int resolution)
|
||||||
|
{
|
||||||
|
int[] acceptedSizes = Cache.getSupportedAvatarResolutions();
|
||||||
|
|
||||||
|
// method to find closest value to accepted values
|
||||||
|
int distance = Math.abs(acceptedSizes[0] - resolution);
|
||||||
|
int idx = 0;
|
||||||
|
for(int c = 1; c < acceptedSizes.length; c++){
|
||||||
|
int cdistance = Math.abs(acceptedSizes[c] - resolution);
|
||||||
|
if(cdistance < distance){
|
||||||
|
idx = c;
|
||||||
|
distance = cdistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return acceptedSizes[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MessageEmbed buildEmbed(int resolution, User user)
|
||||||
|
{
|
||||||
|
int[] acceptedSizes = Cache.getSupportedAvatarResolutions();
|
||||||
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
|
||||||
|
embedBuilder.setColor(Cache.getBotColor());
|
||||||
|
embedBuilder.setTitle("Profile picture");
|
||||||
|
|
||||||
|
embedBuilder.addField("User", "<@" + user.getId() + ">", false);
|
||||||
|
|
||||||
|
embedBuilder.addField("Current resolution", resolution + " × " + resolution, false);
|
||||||
|
|
||||||
|
// string builder to create a string that links to all available resolutions
|
||||||
|
StringBuilder links = new StringBuilder();
|
||||||
|
for(int pos = 0; pos < acceptedSizes.length; pos++)
|
||||||
|
{
|
||||||
|
int currSize = acceptedSizes[pos];
|
||||||
|
|
||||||
|
String currLink = user.getEffectiveAvatar().getUrl(currSize);
|
||||||
|
|
||||||
|
links.append("[").append(currSize).append("px](").append(currLink).append(")");
|
||||||
|
if(pos + 1 != acceptedSizes.length) // don't add a separator on the last iteration
|
||||||
|
{
|
||||||
|
links.append(" | ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
embedBuilder.addField("Available resolutions", links.toString(), false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
embedBuilder.setImage(user.getEffectiveAvatar().getUrl(resolution));
|
||||||
|
return embedBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,10 +7,8 @@ import net.dv8tion.jda.api.entities.channel.Channel;
|
|||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||||
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
|
||||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
import wtf.beatrice.hidekobot.Cache;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -46,12 +44,15 @@ public class ClearChat
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int delete(int toDeleteAmount, long startingMessageId, MessageChannel channel)
|
public static int delete(int toDeleteAmount,
|
||||||
|
long startingMessageId,
|
||||||
|
MessageChannel channel)
|
||||||
{
|
{
|
||||||
// int to keep track of how many messages we actually deleted.
|
// int to keep track of how many messages we actually deleted.
|
||||||
int deleted = 0;
|
int deleted = 0;
|
||||||
|
|
||||||
int limit = 95; //discord limits this method to range 2-100. we set it to 95 to be safe.
|
int limit = 95; //discord limits this method to only 2<x<100 deletions per run.
|
||||||
|
// we set this slightly lower to be safe, and iterate as needed.
|
||||||
|
|
||||||
// increase the count by 1, because we technically aren't clearing the first ID ever
|
// increase the count by 1, because we technically aren't clearing the first ID ever
|
||||||
// which is actually the slash command's ID and not a message.
|
// which is actually the slash command's ID and not a message.
|
||||||
@@ -149,12 +150,13 @@ public class ClearChat
|
|||||||
|
|
||||||
public static Button getDismissButton()
|
public static Button getDismissButton()
|
||||||
{
|
{
|
||||||
return Button.primary("clear_dismiss", "Dismiss")
|
return Button.primary("generic_dismiss", "Dismiss")
|
||||||
.withEmoji(Emoji.fromUnicode("❌"));
|
.withEmoji(Emoji.fromUnicode("❌"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String parseAmount(int deleted)
|
public static String parseAmount(int deleted)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(deleted < 1)
|
if(deleted < 1)
|
||||||
{
|
{
|
||||||
return "\uD83D\uDE22 Couldn't clear any message!";
|
return "\uD83D\uDE22 Couldn't clear any message!";
|
||||||
@@ -166,27 +168,7 @@ public class ClearChat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void respond(Object responseFlowObj, String content)
|
// cap the amount to avoid abuse.
|
||||||
{
|
public static int getMaxAmount() { return 1000; }
|
||||||
if(responseFlowObj instanceof InteractionHook) {
|
|
||||||
((InteractionHook) responseFlowObj).editOriginal(content).queue();
|
|
||||||
} else if (responseFlowObj instanceof Message) {
|
|
||||||
((Message) responseFlowObj).reply(content).queue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void dismissMessage(ButtonInteractionEvent event)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(!(Cache.getDatabaseSource().isUserTrackedFor(event.getUser().getId(), event.getMessageId())))
|
|
||||||
{
|
|
||||||
event.reply("❌ You did not run this command!").setEphemeral(true).queue();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
event.getInteraction().getMessage().delete().queue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class CoinFlip
|
|||||||
|
|
||||||
public static Button getReflipButton() {
|
public static Button getReflipButton() {
|
||||||
return Button.primary("coinflip_reflip", "Flip again")
|
return Button.primary("coinflip_reflip", "Flip again")
|
||||||
.withEmoji(Emoji.fromFormatted("\uD83E\uDE99"));
|
.withEmoji(Emoji.fromUnicode("\uD83E\uDE99"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String genRandom()
|
public static String genRandom()
|
||||||
@@ -61,8 +61,6 @@ public class CoinFlip
|
|||||||
|
|
||||||
public static void trackAndRestrict(Message replyMessage, User user)
|
public static void trackAndRestrict(Message replyMessage, User user)
|
||||||
{
|
{
|
||||||
String replyMessageId = replyMessage.getId();
|
|
||||||
|
|
||||||
Cache.getDatabaseSource().queueDisabling(replyMessage);
|
Cache.getDatabaseSource().queueDisabling(replyMessage);
|
||||||
Cache.getDatabaseSource().trackRanCommandReply(replyMessage, user);
|
Cache.getDatabaseSource().trackRanCommandReply(replyMessage, user);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.base;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
import wtf.beatrice.hidekobot.util.RandomUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MagicBall
|
||||||
|
{
|
||||||
|
|
||||||
|
public static LinkedList<String> getLabels()
|
||||||
|
{
|
||||||
|
return new LinkedList<>(Arrays.asList("8ball", "8b", "eightball", "magicball"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static List<String> answers = new ArrayList<>(
|
||||||
|
Arrays.asList("It is certain.",
|
||||||
|
"It is decidedly so.",
|
||||||
|
"Without a doubt.",
|
||||||
|
"Yes, definitely.",
|
||||||
|
"That would be a yes.",
|
||||||
|
"As I see it, yes.",
|
||||||
|
"Most likely.",
|
||||||
|
"Looks like it.",
|
||||||
|
"Yes.",
|
||||||
|
"Signs point to yes.",
|
||||||
|
"Reply hazy, try again.",
|
||||||
|
"Ask again later.",
|
||||||
|
"Better not tell you now.",
|
||||||
|
"Seems uncertain.",
|
||||||
|
"Concentrate and ask again.",
|
||||||
|
"Don't count on it.",
|
||||||
|
"My answer is no.",
|
||||||
|
"My sources say no.",
|
||||||
|
"Outlook not so good.",
|
||||||
|
"Very doubtful."));
|
||||||
|
|
||||||
|
public static String getRandomAnswer()
|
||||||
|
{
|
||||||
|
int answerPos = RandomUtil.getRandomNumber(0, answers.size() - 1);
|
||||||
|
return answers.get(answerPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MessageEmbed generateEmbed(String question, User author)
|
||||||
|
{
|
||||||
|
// add a question mark at the end, if missing.
|
||||||
|
// this might not always apply but it's fun
|
||||||
|
if(!question.endsWith("?")) question += "?";
|
||||||
|
|
||||||
|
String answer = getRandomAnswer();
|
||||||
|
|
||||||
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
embedBuilder.setAuthor(author.getAsTag(), null, author.getAvatarUrl());
|
||||||
|
embedBuilder.setTitle("Magic Ball");
|
||||||
|
embedBuilder.setColor(Cache.getBotColor());
|
||||||
|
embedBuilder.addField("❓ Question", question, false);
|
||||||
|
embedBuilder.addField("\uD83C\uDFB1 Answer", answer, false);
|
||||||
|
|
||||||
|
return embedBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/main/java/wtf/beatrice/hidekobot/commands/base/Say.java
Normal file
11
src/main/java/wtf/beatrice/hidekobot/commands/base/Say.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.base;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
|
||||||
|
public class Say
|
||||||
|
{
|
||||||
|
|
||||||
|
public static Permission getPermission() {
|
||||||
|
return Permission.MESSAGE_MANAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,320 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.base;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.ItemComponent;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
import org.apache.commons.text.StringEscapeUtils;
|
||||||
|
import org.apache.commons.text.WordUtils;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
import wtf.beatrice.hidekobot.datasources.DatabaseSource;
|
||||||
|
import wtf.beatrice.hidekobot.util.SerializationUtil;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class UrbanDictionary
|
||||||
|
{
|
||||||
|
|
||||||
|
public static LinkedList<String> getCommandLabels()
|
||||||
|
{ return new LinkedList<>(Arrays.asList("urban", "urbandictionary", "ud")); }
|
||||||
|
|
||||||
|
|
||||||
|
public static String getBaseUrl() {
|
||||||
|
return "https://www.urbandictionary.com/define.php?term=";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Button getPreviousPageButton()
|
||||||
|
{
|
||||||
|
return Button.primary("urban_previouspage", "Back")
|
||||||
|
.withEmoji(Emoji.fromFormatted("⬅️"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Button getNextPageButton()
|
||||||
|
{
|
||||||
|
return Button.primary("urban_nextpage", "Next")
|
||||||
|
.withEmoji(Emoji.fromFormatted("➡️"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Button getDeleteButton()
|
||||||
|
{
|
||||||
|
return Button.danger("generic_dismiss", "Delete")
|
||||||
|
.withEmoji(Emoji.fromFormatted("\uD83D\uDDD1️"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNoArgsError() {
|
||||||
|
return "\uD83D\uDE22 I need to know what to search for!";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sanitizeArgs(String term, boolean forUrl)
|
||||||
|
{
|
||||||
|
term = term.replaceAll("[^\\d\\w\\s]", ""); // only keep letters, numbers and spaces
|
||||||
|
term = WordUtils.capitalizeFully(term); // Make Every Word Start With A Capital Letter
|
||||||
|
if(forUrl) term = term.replaceAll("\\s+", "+"); // replace all whitespaces with + for the url
|
||||||
|
if (term.length() > 64) term = term.substring(0, 64); // cut it to length to avoid abuse
|
||||||
|
return term;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateUrl(String term)
|
||||||
|
{
|
||||||
|
return getBaseUrl() + sanitizeArgs(term, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MessageEmbed buildEmbed(String term,
|
||||||
|
String url,
|
||||||
|
User author,
|
||||||
|
UrbanSearch search,
|
||||||
|
int page)
|
||||||
|
{
|
||||||
|
|
||||||
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
embedBuilder.setColor(Cache.getBotColor());
|
||||||
|
embedBuilder.setTitle(term + ", on Urban Dictionary", url);
|
||||||
|
embedBuilder.setAuthor(author.getAsTag(), null, author.getAvatarUrl());
|
||||||
|
embedBuilder.addField("Definition", search.getPlaintextMeanings().get(page), false);
|
||||||
|
embedBuilder.addField("Example", search.getPlaintextExamples().get(page), false);
|
||||||
|
embedBuilder.addField("Submission",
|
||||||
|
"*Entry " + (page+1) + " | Sent by " + search.getContributorsNames().get(page) +
|
||||||
|
" on " + search.getSubmissionDates().get(page) + "*",
|
||||||
|
false);
|
||||||
|
|
||||||
|
return embedBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getTermNotFoundError()
|
||||||
|
{
|
||||||
|
return "\uD83D\uDE22 I couldn't find that term!";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void track(Message message, User user, UrbanSearch search, String sanitizedTerm)
|
||||||
|
{
|
||||||
|
Cache.getDatabaseSource().queueDisabling(message);
|
||||||
|
Cache.getDatabaseSource().trackRanCommandReply(message, user);
|
||||||
|
Cache.getDatabaseSource().trackUrban(search.getSerializedMeanings(),
|
||||||
|
search.getSerializedExamples(),
|
||||||
|
search.getSerializedContributors(),
|
||||||
|
search.getSerializedDates(),
|
||||||
|
message,
|
||||||
|
sanitizedTerm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void changePage(ButtonInteractionEvent event, ChangeType changeType)
|
||||||
|
{
|
||||||
|
String messageId = event.getMessageId();
|
||||||
|
DatabaseSource database = Cache.getDatabaseSource();
|
||||||
|
|
||||||
|
// check if the user interacting is the same one who ran the command
|
||||||
|
if (!(database.isUserTrackedFor(event.getUser().getId(), messageId))) {
|
||||||
|
event.reply("❌ You did not run this command!").setEphemeral(true).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get current page and calculate how many pages there are
|
||||||
|
int page = Cache.getDatabaseSource().getUrbanPage(messageId);
|
||||||
|
|
||||||
|
String term = database.getUrbanTerm(messageId);
|
||||||
|
String url = generateUrl(term);
|
||||||
|
|
||||||
|
// get serialized parameters
|
||||||
|
String serializedMeanings = database.getUrbanMeanings(messageId);
|
||||||
|
String serializedExamples = database.getUrbanExamples(messageId);
|
||||||
|
String serializedContributors = database.getUrbanContributors(messageId);
|
||||||
|
String serializedDates = database.getUrbanDates(messageId);
|
||||||
|
|
||||||
|
// construct object by passing serialized parameters
|
||||||
|
UrbanSearch search = new UrbanSearch(serializedMeanings,
|
||||||
|
serializedExamples, serializedContributors, serializedDates);
|
||||||
|
|
||||||
|
// move to new page
|
||||||
|
if(changeType == ChangeType.NEXT)
|
||||||
|
page++;
|
||||||
|
else if(changeType == ChangeType.PREVIOUS)
|
||||||
|
page--;
|
||||||
|
|
||||||
|
term = UrbanDictionary.sanitizeArgs(term, false);
|
||||||
|
|
||||||
|
// generate embed with new results
|
||||||
|
MessageEmbed updatedEmbed = UrbanDictionary.buildEmbed(term, url, event.getUser(), search, page);
|
||||||
|
|
||||||
|
// get all attached components and check which ones need to be enabled or disabled
|
||||||
|
List<ItemComponent> components = new ArrayList<>();
|
||||||
|
|
||||||
|
if(page > 0)
|
||||||
|
{
|
||||||
|
components.add(UrbanDictionary.getPreviousPageButton().asEnabled());
|
||||||
|
} else {
|
||||||
|
components.add(UrbanDictionary.getPreviousPageButton().asDisabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(page + 1 == search.getPages())
|
||||||
|
{
|
||||||
|
components.add(UrbanDictionary.getNextPageButton().asDisabled());
|
||||||
|
} else {
|
||||||
|
components.add(UrbanDictionary.getNextPageButton().asEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the components on the object
|
||||||
|
components.add(UrbanDictionary.getDeleteButton());
|
||||||
|
ActionRow currentRow = ActionRow.of(components);
|
||||||
|
|
||||||
|
// update the message
|
||||||
|
event.editComponents(currentRow).setEmbeds(updatedEmbed).queue();
|
||||||
|
database.setUrbanPage(messageId, page);
|
||||||
|
database.resetExpiryTimestamp(messageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UrbanSearch
|
||||||
|
{
|
||||||
|
final LinkedList<String> plaintextMeanings;
|
||||||
|
final LinkedList<String> plaintextExamples;
|
||||||
|
final LinkedList<String> contributorsNames;
|
||||||
|
final LinkedList<String> submissionDates;
|
||||||
|
|
||||||
|
final String serializedMeanings;
|
||||||
|
final String serializedExamples;
|
||||||
|
final String serializedContributors;
|
||||||
|
final String serializedDates;
|
||||||
|
|
||||||
|
final int pages;
|
||||||
|
|
||||||
|
public UrbanSearch(String serializedMeanings,
|
||||||
|
String serializedExamples,
|
||||||
|
String serializedContributors,
|
||||||
|
String serializedDates)
|
||||||
|
{
|
||||||
|
this.serializedMeanings = serializedMeanings;
|
||||||
|
this.serializedExamples = serializedExamples;
|
||||||
|
this.serializedContributors = serializedContributors;
|
||||||
|
this.serializedDates = serializedDates;
|
||||||
|
|
||||||
|
this.plaintextMeanings = SerializationUtil.deserializeBase64(serializedMeanings);
|
||||||
|
this.plaintextExamples = SerializationUtil.deserializeBase64(serializedExamples);
|
||||||
|
this.contributorsNames = SerializationUtil.deserializeBase64(serializedContributors);
|
||||||
|
this.submissionDates = SerializationUtil.deserializeBase64(serializedDates);
|
||||||
|
|
||||||
|
this.pages = submissionDates.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UrbanSearch(Elements definitions)
|
||||||
|
{
|
||||||
|
plaintextMeanings = new LinkedList<>();
|
||||||
|
plaintextExamples = new LinkedList<>();
|
||||||
|
contributorsNames = new LinkedList<>();
|
||||||
|
submissionDates = new LinkedList<>();
|
||||||
|
|
||||||
|
for(Element definition : definitions)
|
||||||
|
{
|
||||||
|
Elements meaningSingleton = definition.getElementsByClass("meaning");
|
||||||
|
if(meaningSingleton.isEmpty())
|
||||||
|
{
|
||||||
|
plaintextMeanings.add(" ");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
Element meaning = meaningSingleton.get(0);
|
||||||
|
String text = meaning.html()
|
||||||
|
.replaceAll("<br\\s*?>", "\n") // keep newlines
|
||||||
|
.replaceAll("<.*?>", ""); // remove all other html tags
|
||||||
|
// this is used to fix eg. & being shown literally instead of being parsed
|
||||||
|
text = StringEscapeUtils.unescapeHtml4(text);
|
||||||
|
// discord only allows 1024 characters for embed fields
|
||||||
|
if(text.length() > 1024) text = text.substring(0, 1020) + "...";
|
||||||
|
plaintextMeanings.add(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
Elements exampleSingleton = definition.getElementsByClass("example");
|
||||||
|
|
||||||
|
if(exampleSingleton.isEmpty())
|
||||||
|
{
|
||||||
|
plaintextExamples.add(" ");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
Element example = exampleSingleton.get(0);
|
||||||
|
String text = example.html()
|
||||||
|
.replaceAll("<br\\s*?>", "\n") // keep newlines
|
||||||
|
.replaceAll("<.*?>", ""); // remove all other html tags
|
||||||
|
// this is used to fix eg. & being shown literally instead of being parsed
|
||||||
|
text = StringEscapeUtils.unescapeHtml4(text);
|
||||||
|
// discord only allows 1024 characters for embed fields
|
||||||
|
if(text.length() > 1024) text = text.substring(0, 1020) + "...";
|
||||||
|
plaintextExamples.add(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
Elements contributorSingleton = definition.getElementsByClass("contributor");
|
||||||
|
if(contributorSingleton.isEmpty())
|
||||||
|
{
|
||||||
|
contributorsNames.add("Unknown");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
Element contributor = contributorSingleton.get(0);
|
||||||
|
|
||||||
|
String htmlContributor = contributor.html();
|
||||||
|
String htmlContributorName = contributor.select("a").html();
|
||||||
|
String htmlSubmitDate = htmlContributor.substring(
|
||||||
|
htmlContributor.indexOf("</a>") + 4);
|
||||||
|
|
||||||
|
contributorsNames.add(htmlContributorName
|
||||||
|
.replaceAll("<.*?>", "")); // remove all html tags;
|
||||||
|
|
||||||
|
submissionDates.add(htmlSubmitDate
|
||||||
|
.replaceAll("<.*?>", "")); // remove all html tags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serializedMeanings = SerializationUtil.serializeBase64(plaintextMeanings);
|
||||||
|
serializedExamples = SerializationUtil.serializeBase64(plaintextExamples);
|
||||||
|
serializedContributors = SerializationUtil.serializeBase64(contributorsNames);
|
||||||
|
serializedDates = SerializationUtil.serializeBase64(submissionDates);
|
||||||
|
|
||||||
|
pages = submissionDates.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPlaintextMeanings() {
|
||||||
|
return this.plaintextMeanings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPlaintextExamples() {
|
||||||
|
return this.plaintextExamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getContributorsNames() {
|
||||||
|
return this.contributorsNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSubmissionDates() {
|
||||||
|
return this.submissionDates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSerializedMeanings() {
|
||||||
|
return serializedMeanings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSerializedExamples() {
|
||||||
|
return serializedExamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSerializedContributors() {
|
||||||
|
return serializedContributors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSerializedDates() {
|
||||||
|
return serializedDates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPages() {
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ChangeType
|
||||||
|
{
|
||||||
|
NEXT,
|
||||||
|
PREVIOUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.message;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.Alias;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AliasCommand implements MessageCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedList<String> getCommandLabels() {
|
||||||
|
return new LinkedList<>(Arrays.asList("alias", "aliases"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<Permission> getPermissions() {
|
||||||
|
return null; // anyone can use it
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean passRawArgs() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.TOOLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "See other command aliases.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "<command>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
|
{
|
||||||
|
if(args.length == 0)
|
||||||
|
{
|
||||||
|
event.getMessage().reply("\uD83D\uDE20 Hey, you have to specify a command!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String commandLabel = args[0].toLowerCase();
|
||||||
|
MessageCommand command = Cache.getMessageCommandListener().getRegisteredCommand(commandLabel);
|
||||||
|
if(command == null)
|
||||||
|
{
|
||||||
|
event.getMessage().reply("Unrecognized command: `" + commandLabel + "`!").queue(); // todo prettier
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String aliases = Alias.generateNiceAliases(command);
|
||||||
|
aliases = "Aliases for **" + command.getCommandLabels().get(0) + "**: " + aliases;
|
||||||
|
|
||||||
|
event.getMessage()
|
||||||
|
.reply(aliases)
|
||||||
|
.queue();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.message;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.Mentions;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
import wtf.beatrice.hidekobot.HidekoBot;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.Avatar;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AvatarCommand implements MessageCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedList<String> getCommandLabels() {
|
||||||
|
return new LinkedList<>(Collections.singletonList("avatar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<Permission> getPermissions() {
|
||||||
|
return null; // anyone can use it
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean passRawArgs() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Get someone's avatar, or your own. You can additionally specify a resolution.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "[mentioned user] [resolution]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.TOOLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
|
{
|
||||||
|
int[] acceptedSizes = Cache.getSupportedAvatarResolutions();
|
||||||
|
|
||||||
|
User user;
|
||||||
|
int resolution = -1;
|
||||||
|
|
||||||
|
// we have no specific order for user and resolution, so let's try parsing any arg as resolution
|
||||||
|
// (mentions are handled differently by a specific method)
|
||||||
|
boolean resFound = false;
|
||||||
|
|
||||||
|
for (String arg : args) {
|
||||||
|
try {
|
||||||
|
int givenRes = Integer.parseInt(arg);
|
||||||
|
resolution = Avatar.parseResolution(givenRes);
|
||||||
|
resFound = true;
|
||||||
|
break;
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback in case we didn't find any specified resolution
|
||||||
|
if(!resFound) resolution = Avatar.parseResolution(512);
|
||||||
|
|
||||||
|
// check if someone is mentioned
|
||||||
|
Mentions mentions = event.getMessage().getMentions();
|
||||||
|
if(mentions.getMentions().isEmpty())
|
||||||
|
{
|
||||||
|
user = event.getAuthor();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
String mentionedId = mentions.getMentions().get(0).getId();
|
||||||
|
user = HidekoBot.getAPI().retrieveUserById(mentionedId).complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// in case of issues, fallback to the sender
|
||||||
|
if(user == null) user = event.getAuthor();
|
||||||
|
|
||||||
|
// send a response
|
||||||
|
MessageEmbed embed = Avatar.buildEmbed(resolution, user);
|
||||||
|
event.getMessage().replyEmbeds(embed).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,11 @@ package wtf.beatrice.hidekobot.commands.message;
|
|||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import wtf.beatrice.hidekobot.Cache;
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
import wtf.beatrice.hidekobot.commands.base.BotInfo;
|
import wtf.beatrice.hidekobot.commands.base.BotInfo;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -31,6 +33,24 @@ public class BotInfoCommand implements MessageCommand
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Get general info about the bot.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.TOOLS;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(MessageReceivedEvent event, String label, String[] args) {
|
public void runCommand(MessageReceivedEvent event, String label, String[] args) {
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ import net.dv8tion.jda.api.Permission;
|
|||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import wtf.beatrice.hidekobot.Cache;
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
import wtf.beatrice.hidekobot.commands.base.ClearChat;
|
import wtf.beatrice.hidekobot.commands.base.ClearChat;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -28,6 +31,24 @@ public class ClearCommand implements MessageCommand
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.MODERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Clear the current channel's chat history.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "[amount]";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
{
|
{
|
||||||
@@ -43,7 +64,18 @@ public class ClearCommand implements MessageCommand
|
|||||||
// get the amount from the command args.
|
// get the amount from the command args.
|
||||||
Integer toDeleteAmount;
|
Integer toDeleteAmount;
|
||||||
if (args.length == 0) toDeleteAmount = 1;
|
if (args.length == 0) toDeleteAmount = 1;
|
||||||
else toDeleteAmount = Integer.parseInt(args[0]);
|
else
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
toDeleteAmount = Integer.parseInt(args[0]);
|
||||||
|
} catch (NumberFormatException e)
|
||||||
|
{
|
||||||
|
toDeleteAmount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cap the amount to avoid abuse.
|
||||||
|
if(toDeleteAmount > ClearChat.getMaxAmount()) toDeleteAmount = 0;
|
||||||
|
|
||||||
error = ClearChat.checkDeleteAmount(toDeleteAmount);
|
error = ClearChat.checkDeleteAmount(toDeleteAmount);
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
@@ -64,14 +96,16 @@ public class ClearCommand implements MessageCommand
|
|||||||
|
|
||||||
// edit the message text and attach a button.
|
// edit the message text and attach a button.
|
||||||
Button dismiss = ClearChat.getDismissButton();
|
Button dismiss = ClearChat.getDismissButton();
|
||||||
// ^ todo: maybe the dismiss button should also delete the original message sent by the user?
|
Message finalMessage = event.getChannel().sendMessage(content).setActionRow(dismiss).complete();
|
||||||
// todo: but then, we need to differentiate between command type in the database, and store
|
|
||||||
// todo: that message's id too.
|
|
||||||
botMessage = botMessage.editMessage(content).setActionRow(dismiss).complete();
|
|
||||||
|
|
||||||
// add the message to database.
|
// add the message to database.
|
||||||
Cache.getDatabaseSource().queueDisabling(botMessage);
|
Cache.getDatabaseSource().queueDisabling(finalMessage);
|
||||||
Cache.getDatabaseSource().trackRanCommandReply(botMessage, event.getAuthor());
|
Cache.getDatabaseSource().trackRanCommandReply(finalMessage, event.getAuthor());
|
||||||
|
|
||||||
|
// delete the sender's message.
|
||||||
|
event.getMessage().delete().queue();
|
||||||
|
// delete the "clearing" info message.
|
||||||
|
botMessage.delete().queue();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package wtf.beatrice.hidekobot.commands.message;
|
|||||||
|
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import wtf.beatrice.hidekobot.commands.base.CoinFlip;
|
import wtf.beatrice.hidekobot.commands.base.CoinFlip;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -29,6 +31,24 @@ public class CoinFlipCommand implements MessageCommand
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Flip a coin.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.FUN;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(MessageReceivedEvent event, String label, String[] args) {
|
public void runCommand(MessageReceivedEvent event, String label, String[] args) {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,195 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.message;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
import wtf.beatrice.hidekobot.objects.Dice;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class DiceRollCommand implements MessageCommand
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public LinkedList<String> getCommandLabels() {
|
||||||
|
return new LinkedList<>(Arrays.asList("diceroll", "droll", "roll"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<Permission> getPermissions() {
|
||||||
|
return null; // anyone can use it
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean passRawArgs() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Roll dice. You can roll multiple dice at the same time." +
|
||||||
|
"\nExamples:" +
|
||||||
|
"\n - `d8 10` to roll an 8-sided die 10 times." +
|
||||||
|
"\n - `d12 3 d5 10` to roll a 12-sided die 3 times, and then a 5-sided die 10 times." +
|
||||||
|
"\n - `30` to roll a standard 6-sided die 30 times." +
|
||||||
|
"\n - `d10` to roll a 10-sided die once.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "[dice size] [rolls]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.FUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
|
{
|
||||||
|
LinkedHashMap<Dice, Integer> dicesToRoll = new LinkedHashMap<>();
|
||||||
|
String diceRegex = "d[0-9]+";
|
||||||
|
String amountRegex = "[0-9]+";
|
||||||
|
|
||||||
|
Dice currentDice = null;
|
||||||
|
int currentAmount;
|
||||||
|
UUID lastPushedDice = null;
|
||||||
|
int totalRolls = 0;
|
||||||
|
|
||||||
|
for(String arg : args)
|
||||||
|
{
|
||||||
|
if(totalRolls > 200)
|
||||||
|
{
|
||||||
|
event.getMessage().reply("Too many total rolls!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(arg.matches(amountRegex))
|
||||||
|
{
|
||||||
|
currentAmount = Integer.parseInt(arg);
|
||||||
|
|
||||||
|
if(currentDice == null)
|
||||||
|
{
|
||||||
|
currentDice = new Dice(6);
|
||||||
|
} else {
|
||||||
|
currentDice = new Dice(currentDice);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentAmount > 100)
|
||||||
|
{
|
||||||
|
event.getMessage().reply("Too many rolls (`" + currentAmount + "`)!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPushedDice = currentDice.getUUID();
|
||||||
|
dicesToRoll.put(currentDice, currentAmount);
|
||||||
|
totalRolls += currentAmount;
|
||||||
|
}
|
||||||
|
else if(arg.matches(diceRegex))
|
||||||
|
{
|
||||||
|
int sides = Integer.parseInt(arg.substring(1));
|
||||||
|
|
||||||
|
if(sides > 10000)
|
||||||
|
{
|
||||||
|
event.getMessage().reply("Too many sides (`" + sides + "`)!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args.length == 1)
|
||||||
|
{
|
||||||
|
dicesToRoll.put(new Dice(sides), 1);
|
||||||
|
totalRolls++;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if(currentDice != null)
|
||||||
|
{
|
||||||
|
if(lastPushedDice == null || !lastPushedDice.equals(currentDice.getUUID()))
|
||||||
|
{
|
||||||
|
dicesToRoll.put(currentDice, 1);
|
||||||
|
lastPushedDice = currentDice.getUUID();
|
||||||
|
totalRolls++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDice = new Dice(sides);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lastPushedDice == null)
|
||||||
|
{
|
||||||
|
if(currentDice != null)
|
||||||
|
{
|
||||||
|
dicesToRoll.put(currentDice, 1);
|
||||||
|
totalRolls++;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if(!lastPushedDice.equals(currentDice.getUUID()))
|
||||||
|
{
|
||||||
|
dicesToRoll.put(new Dice(currentDice), 1);
|
||||||
|
totalRolls++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedList<Dice> rolledDices = new LinkedList<>();
|
||||||
|
|
||||||
|
for(Dice dice : dicesToRoll.keySet())
|
||||||
|
{
|
||||||
|
for(int roll = 0; roll < dicesToRoll.get(dice); roll++)
|
||||||
|
{
|
||||||
|
dice.roll();
|
||||||
|
rolledDices.add(new Dice(dice));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
|
||||||
|
embedBuilder.setColor(Cache.getBotColor());
|
||||||
|
embedBuilder.setAuthor(event.getAuthor().getAsTag(), null, event.getAuthor().getAvatarUrl());
|
||||||
|
embedBuilder.setTitle("Dice Roll");
|
||||||
|
|
||||||
|
StringBuilder message = new StringBuilder();
|
||||||
|
int total = 0;
|
||||||
|
|
||||||
|
int previousDiceSides = 0;
|
||||||
|
for (Dice dice : rolledDices) {
|
||||||
|
int diceSize = dice.getSides();
|
||||||
|
|
||||||
|
if (previousDiceSides != diceSize) {
|
||||||
|
message.append("\nd").append(diceSize).append(": ");
|
||||||
|
previousDiceSides = diceSize;
|
||||||
|
} else if (previousDiceSides != 0) {
|
||||||
|
message.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
message.append("`").append(dice.getValue()).append("`");
|
||||||
|
|
||||||
|
total += dice.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// discord doesn't allow embed fields to be longer than 1024 and errors out
|
||||||
|
if(message.length() > 1024)
|
||||||
|
{
|
||||||
|
event.getMessage().reply("Too many rolls!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
embedBuilder.addField("\uD83C\uDFB2 Rolls", message.toString(), false);
|
||||||
|
|
||||||
|
embedBuilder.addField("✨ Total", totalRolls + " rolls: " + total, false);
|
||||||
|
|
||||||
|
|
||||||
|
event.getMessage().replyEmbeds(embedBuilder.build()).queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,6 +2,9 @@ package wtf.beatrice.hidekobot.commands.message;
|
|||||||
|
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -24,6 +27,24 @@ public class HelloCommand implements MessageCommand
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Get pinged by the bot.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.FUN;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,155 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.message;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.apache.commons.text.WordUtils;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.Alias;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.Say;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HelpCommand implements MessageCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedList<String> getCommandLabels() {
|
||||||
|
return new LinkedList<>(Collections.singletonList("help"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<Permission> getPermissions() { return null; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean passRawArgs() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Get general help on the bot. Specify a command if you want specific help about that command.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "[command]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.TOOLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
|
{
|
||||||
|
LinkedHashMap<CommandCategory, LinkedList<MessageCommand>> commandCategories = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
if(args.length == 0)
|
||||||
|
{
|
||||||
|
for(CommandCategory category : CommandCategory.values())
|
||||||
|
{
|
||||||
|
LinkedList<MessageCommand> commandsOfThisCategory = new LinkedList<>();
|
||||||
|
for (MessageCommand command : Cache.getMessageCommandListener().getRegisteredCommands())
|
||||||
|
{
|
||||||
|
if(command.getCategory().equals(category))
|
||||||
|
{
|
||||||
|
commandsOfThisCategory.add(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commandCategories.put(category, commandsOfThisCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
embedBuilder.setColor(Cache.getBotColor());
|
||||||
|
embedBuilder.setTitle("Bot Help");
|
||||||
|
|
||||||
|
embedBuilder.addField("General Help",
|
||||||
|
"Type `" + Cache.getBotPrefix() + " help [command]` to get help on a specific command." +
|
||||||
|
"\nYou will find a list of commands organized in categories below.",
|
||||||
|
false);
|
||||||
|
|
||||||
|
for(CommandCategory category : commandCategories.keySet())
|
||||||
|
{
|
||||||
|
StringBuilder commandsList = new StringBuilder();
|
||||||
|
LinkedList<MessageCommand> commandsOfThisCategory = commandCategories.get(category);
|
||||||
|
|
||||||
|
for(int pos = 0; pos < commandsOfThisCategory.size(); pos++)
|
||||||
|
{
|
||||||
|
MessageCommand command = commandsOfThisCategory.get(pos);
|
||||||
|
commandsList.append("`").append(command.getCommandLabels().get(0)).append("`");
|
||||||
|
|
||||||
|
if(pos + 1 != commandsOfThisCategory.size())
|
||||||
|
commandsList.append(", "); // separate with comma except on last run
|
||||||
|
}
|
||||||
|
|
||||||
|
String niceCategoryName = category.name().replace("_", " ");
|
||||||
|
niceCategoryName = WordUtils.capitalizeFully(niceCategoryName);
|
||||||
|
niceCategoryName = category.getEmoji() + " " + niceCategoryName;
|
||||||
|
|
||||||
|
embedBuilder.addField(niceCategoryName, commandsList.toString(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
event.getMessage().replyEmbeds(embedBuilder.build()).queue();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
String commandLabel = args[0].toLowerCase();
|
||||||
|
MessageCommand command = Cache.getMessageCommandListener().getRegisteredCommand(commandLabel);
|
||||||
|
if(command == null)
|
||||||
|
{
|
||||||
|
event.getMessage().reply("Unrecognized command: `" + commandLabel + "`!").queue(); // todo prettier
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
commandLabel = command.getCommandLabels().get(0);
|
||||||
|
String usage = "`" + Cache.getBotPrefix() + " " + commandLabel;
|
||||||
|
String internalUsage = command.getUsage();
|
||||||
|
if(internalUsage != null) usage += " " + internalUsage;
|
||||||
|
usage += "`";
|
||||||
|
|
||||||
|
String aliases = Alias.generateNiceAliases(command);
|
||||||
|
|
||||||
|
List<Permission> permissions = command.getPermissions();
|
||||||
|
StringBuilder permissionsStringBuilder = new StringBuilder();
|
||||||
|
if(permissions == null)
|
||||||
|
{
|
||||||
|
permissionsStringBuilder = new StringBuilder("Available to everyone");
|
||||||
|
} else {
|
||||||
|
for(int i = 0; i < permissions.size(); i++)
|
||||||
|
{
|
||||||
|
Permission permission = permissions.get(i);
|
||||||
|
permissionsStringBuilder.append("`").append(permission.getName()).append("`");
|
||||||
|
|
||||||
|
if(i + 1 != permissions.size())
|
||||||
|
permissionsStringBuilder.append(", "); // separate with comma expect on last iteration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
|
||||||
|
embedBuilder.setColor(Cache.getBotColor());
|
||||||
|
embedBuilder.setTitle(WordUtils.capitalizeFully(commandLabel + " help"));
|
||||||
|
|
||||||
|
embedBuilder.addField("Description", command.getDescription(), false);
|
||||||
|
embedBuilder.addField("Usage", usage, false);
|
||||||
|
embedBuilder.addField("Aliases", aliases, false);
|
||||||
|
embedBuilder.addField("Permissions", permissionsStringBuilder.toString(), false);
|
||||||
|
|
||||||
|
event.getMessage().replyEmbeds(embedBuilder.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,8 +5,10 @@ import net.dv8tion.jda.api.entities.MessageEmbed;
|
|||||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import wtf.beatrice.hidekobot.commands.base.Invite;
|
import wtf.beatrice.hidekobot.commands.base.Invite;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -32,6 +34,24 @@ public class InviteCommand implements MessageCommand
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Get the bot's invite link.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.FUN;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.message;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.IMentionable;
|
||||||
|
import net.dv8tion.jda.api.entities.Mentions;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
import wtf.beatrice.hidekobot.HidekoBot;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
import wtf.beatrice.hidekobot.util.RandomUtil;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LoveCalculatorCommand implements MessageCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedList<String> getCommandLabels()
|
||||||
|
{
|
||||||
|
return new LinkedList<>(Arrays.asList("lovecalc", "lovecalculator", "lc"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<Permission> getPermissions() {
|
||||||
|
return null; //anyone can use it
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean passRawArgs() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Calculate how much two people love each other. You can mention two people or just one.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "<person 1> [person 2]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.FUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
Mentions mentionsObj = event.getMessage().getMentions();
|
||||||
|
List<IMentionable> mentions = mentionsObj.getMentions();
|
||||||
|
|
||||||
|
|
||||||
|
if(args.length == 0 || mentions.isEmpty())
|
||||||
|
{
|
||||||
|
event.getMessage()
|
||||||
|
.reply("\uD83D\uDE22 I need to know who to check! Please mention them.")
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
User user1, user2;
|
||||||
|
|
||||||
|
String mentionedUserId = mentions.get(0).getId();
|
||||||
|
user1 = HidekoBot.getAPI().retrieveUserById(mentionedUserId).complete();
|
||||||
|
|
||||||
|
if(mentions.size() == 1)
|
||||||
|
{
|
||||||
|
user2 = event.getAuthor();
|
||||||
|
} else {
|
||||||
|
mentionedUserId = mentions.get(1).getId();
|
||||||
|
user2 = HidekoBot.getAPI().retrieveUserById(mentionedUserId).complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
int loveAmount = RandomUtil.getRandomNumber(0, 100);
|
||||||
|
|
||||||
|
String formattedAmount = loveAmount + "%";
|
||||||
|
if(loveAmount <= 30) formattedAmount += "... \uD83D\uDE22";
|
||||||
|
else if(loveAmount < 60) formattedAmount += "! \uD83E\uDDD0";
|
||||||
|
else if(loveAmount < 75) formattedAmount += "!!! \uD83E\uDD73";
|
||||||
|
else formattedAmount = "✨ " + formattedAmount + "!!! \uD83D\uDE0D\uD83D\uDCA5";
|
||||||
|
|
||||||
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
embedBuilder.setColor(Cache.getBotColor());
|
||||||
|
embedBuilder.setAuthor(event.getAuthor().getAsTag(), null, event.getAuthor().getAvatarUrl());
|
||||||
|
embedBuilder.setTitle("Love Calculator");
|
||||||
|
|
||||||
|
embedBuilder.addField("\uD83D\uDC65 People",
|
||||||
|
user1.getAsMention() + " & " + user2.getAsMention(),
|
||||||
|
false);
|
||||||
|
|
||||||
|
embedBuilder.addField("❤️\u200D\uD83D\uDD25 Match",
|
||||||
|
formattedAmount,
|
||||||
|
false);
|
||||||
|
|
||||||
|
event.getChannel().sendMessageEmbeds(embedBuilder.build()).queue();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.message;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.MagicBall;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MagicBallCommand implements MessageCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedList<String> getCommandLabels() {
|
||||||
|
return MagicBall.getLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<Permission> getPermissions() {
|
||||||
|
return null; // anyone can use it
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean passRawArgs() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Ask a question to the Magic Ball.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "<question>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.FUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
|
{
|
||||||
|
if(args.length == 0)
|
||||||
|
{
|
||||||
|
event.getMessage().reply("You need to specify a question!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder questionBuilder = new StringBuilder();
|
||||||
|
for(int i = 0; i < args.length; i++)
|
||||||
|
{
|
||||||
|
String arg = args[i];
|
||||||
|
questionBuilder.append(arg);
|
||||||
|
if(i + 1 != args.length) // don't add a separator on the last iteration
|
||||||
|
questionBuilder.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
String question = questionBuilder.toString();
|
||||||
|
|
||||||
|
|
||||||
|
event.getChannel().sendMessageEmbeds(MagicBall.generateEmbed(question, event.getAuthor())).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.message;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.Say;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SayCommand implements MessageCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedList<String> getCommandLabels() {
|
||||||
|
return new LinkedList<>(Collections.singletonList("say"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<Permission> getPermissions() { return Collections.singletonList(Say.getPermission()); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean passRawArgs() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Make the bot say something for you.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "<text>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.TOOLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
String messageContent;
|
||||||
|
if(args.length != 0 && !args[0].isEmpty())
|
||||||
|
{
|
||||||
|
messageContent = args[0];
|
||||||
|
} else {
|
||||||
|
event.getMessage().reply("\uD83D\uDE20 Hey, you have to tell me what to say!")
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.getChannel().sendMessage(messageContent).queue();
|
||||||
|
event.getMessage().delete().queue();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.message;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.UrbanDictionary;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UrbanDictionaryCommand implements MessageCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedList<String> getCommandLabels() {
|
||||||
|
return UrbanDictionary.getCommandLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<Permission> getPermissions() {
|
||||||
|
return null; //anyone can use it
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean passRawArgs() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Look something up in the Urban Dictionary.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "<query>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.FUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runCommand(MessageReceivedEvent event, String label, String[] args)
|
||||||
|
{
|
||||||
|
if(args.length == 0)
|
||||||
|
{
|
||||||
|
event.getMessage().reply(UrbanDictionary.getNoArgsError()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanitize args by only keeping letters and numbers, and adding "+" instead of spaces for HTML parsing
|
||||||
|
StringBuilder termBuilder = new StringBuilder();
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
String arg = args[i];
|
||||||
|
termBuilder.append(arg);
|
||||||
|
|
||||||
|
if(i + 1 != args.length) // add spaces between args, but not on the last run
|
||||||
|
termBuilder.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
String term = UrbanDictionary.sanitizeArgs(termBuilder.toString(), false);
|
||||||
|
String url = UrbanDictionary.generateUrl(term);
|
||||||
|
|
||||||
|
Document doc;
|
||||||
|
|
||||||
|
try {
|
||||||
|
doc = Jsoup.connect(url).get();
|
||||||
|
} catch (IOException e) {
|
||||||
|
event.getMessage().reply(UrbanDictionary.getTermNotFoundError()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Elements definitions = doc.getElementsByClass("definition");
|
||||||
|
UrbanDictionary.UrbanSearch search = new UrbanDictionary.UrbanSearch(definitions);
|
||||||
|
MessageEmbed embed = UrbanDictionary.buildEmbed(term, url, event.getAuthor(), search, 0);
|
||||||
|
|
||||||
|
// disable next page if we only have one result
|
||||||
|
Button nextPageBtnLocal = UrbanDictionary.getNextPageButton();
|
||||||
|
if(search.getPages() == 1) nextPageBtnLocal = nextPageBtnLocal.asDisabled();
|
||||||
|
|
||||||
|
event.getChannel()
|
||||||
|
.sendMessageEmbeds(embed)
|
||||||
|
.addActionRow(UrbanDictionary.getPreviousPageButton().asDisabled(),
|
||||||
|
//disabled by default because we're on page 0
|
||||||
|
nextPageBtnLocal,
|
||||||
|
UrbanDictionary.getDeleteButton())
|
||||||
|
.queue(message -> UrbanDictionary.track(message, event.getAuthor(), search, term));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package wtf.beatrice.hidekobot.commands.slash;
|
package wtf.beatrice.hidekobot.commands.slash;
|
||||||
|
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
@@ -8,7 +8,7 @@ import net.dv8tion.jda.api.interactions.commands.OptionType;
|
|||||||
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import wtf.beatrice.hidekobot.Cache;
|
import wtf.beatrice.hidekobot.commands.base.Avatar;
|
||||||
import wtf.beatrice.hidekobot.objects.commands.SlashCommandImpl;
|
import wtf.beatrice.hidekobot.objects.commands.SlashCommandImpl;
|
||||||
|
|
||||||
public class AvatarCommand extends SlashCommandImpl
|
public class AvatarCommand extends SlashCommandImpl
|
||||||
@@ -31,9 +31,6 @@ public class AvatarCommand extends SlashCommandImpl
|
|||||||
User user;
|
User user;
|
||||||
int resolution;
|
int resolution;
|
||||||
|
|
||||||
int[] acceptedSizes = Cache.getSupportedAvatarResolutions();
|
|
||||||
|
|
||||||
|
|
||||||
OptionMapping userArg = event.getOption("user");
|
OptionMapping userArg = event.getOption("user");
|
||||||
if(userArg != null)
|
if(userArg != null)
|
||||||
{
|
{
|
||||||
@@ -45,57 +42,12 @@ public class AvatarCommand extends SlashCommandImpl
|
|||||||
OptionMapping sizeArg = event.getOption("size");
|
OptionMapping sizeArg = event.getOption("size");
|
||||||
if(sizeArg != null)
|
if(sizeArg != null)
|
||||||
{
|
{
|
||||||
resolution = sizeArg.getAsInt();
|
resolution = Avatar.parseResolution(sizeArg.getAsInt());
|
||||||
|
|
||||||
// method to find closest value to accepted values
|
|
||||||
int distance = Math.abs(acceptedSizes[0] - resolution);
|
|
||||||
int idx = 0;
|
|
||||||
for(int c = 1; c < acceptedSizes.length; c++){
|
|
||||||
int cdistance = Math.abs(acceptedSizes[c] - resolution);
|
|
||||||
if(cdistance < distance){
|
|
||||||
idx = c;
|
|
||||||
distance = cdistance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolution = acceptedSizes[idx];
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
resolution = 512;
|
resolution = Avatar.parseResolution(512);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
MessageEmbed embed = Avatar.buildEmbed(resolution, user);
|
||||||
|
event.getHook().editOriginalEmbeds(embed).queue();
|
||||||
// embed processing
|
|
||||||
{
|
|
||||||
embedBuilder.setColor(Cache.getBotColor());
|
|
||||||
embedBuilder.setTitle("Profile picture");
|
|
||||||
|
|
||||||
embedBuilder.addField("User", "<@" + user.getId() + ">", false);
|
|
||||||
|
|
||||||
embedBuilder.addField("Current resolution", resolution + " × " + resolution, false);
|
|
||||||
|
|
||||||
// string builder to create a string that links to all available resolutions
|
|
||||||
StringBuilder links = new StringBuilder();
|
|
||||||
for(int pos = 0; pos < acceptedSizes.length; pos++)
|
|
||||||
{
|
|
||||||
int currSize = acceptedSizes[pos];
|
|
||||||
|
|
||||||
String currLink = user.getEffectiveAvatar().getUrl(currSize);
|
|
||||||
|
|
||||||
links.append("[").append(currSize).append("px](").append(currLink).append(")");
|
|
||||||
if(pos + 1 != acceptedSizes.length) // don't add a separator on the last iteration
|
|
||||||
{
|
|
||||||
links.append(" | ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
embedBuilder.addField("Available resolutions", links.toString(), false);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
embedBuilder.setImage(user.getEffectiveAvatar().getUrl(resolution));
|
|
||||||
}
|
|
||||||
|
|
||||||
event.getHook().editOriginalEmbeds(embedBuilder.build()).queue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ public class ClearCommand extends SlashCommandImpl
|
|||||||
OptionMapping amountOption = event.getOption("amount");
|
OptionMapping amountOption = event.getOption("amount");
|
||||||
int toDeleteAmount = amountOption == null ? 1 : amountOption.getAsInt();
|
int toDeleteAmount = amountOption == null ? 1 : amountOption.getAsInt();
|
||||||
|
|
||||||
|
// cap the amount to avoid abuse.
|
||||||
|
if(toDeleteAmount > ClearChat.getMaxAmount()) toDeleteAmount = 0;
|
||||||
|
|
||||||
error = ClearChat.checkDeleteAmount(toDeleteAmount);
|
error = ClearChat.checkDeleteAmount(toDeleteAmount);
|
||||||
if(error != null)
|
if(error != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.slash;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.MagicBall;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.SlashCommandImpl;
|
||||||
|
|
||||||
|
public class MagicBallCommand extends SlashCommandImpl
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public CommandData getSlashCommandData()
|
||||||
|
{
|
||||||
|
|
||||||
|
return Commands.slash(MagicBall.getLabels().get(0),
|
||||||
|
"Ask a question to the magic ball.")
|
||||||
|
.addOption(OptionType.STRING, "question",
|
||||||
|
"The question to ask.",
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
|
||||||
|
{
|
||||||
|
// get the asked question
|
||||||
|
OptionMapping textOption = event.getOption("question");
|
||||||
|
String question = "";
|
||||||
|
if(textOption != null)
|
||||||
|
{
|
||||||
|
question = textOption.getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(textOption == null || question.isEmpty())
|
||||||
|
{
|
||||||
|
event.reply("\uD83D\uDE20 Hey, you have to ask me a question!")
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageEmbed response = MagicBall.generateEmbed(question, event.getUser());
|
||||||
|
event.replyEmbeds(response).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package wtf.beatrice.hidekobot.commands.slash;
|
package wtf.beatrice.hidekobot.commands.slash;
|
||||||
|
|
||||||
import net.dv8tion.jda.api.Permission;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
|
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
|
||||||
@@ -9,6 +8,7 @@ import net.dv8tion.jda.api.interactions.commands.OptionType;
|
|||||||
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.Say;
|
||||||
import wtf.beatrice.hidekobot.objects.commands.SlashCommandImpl;
|
import wtf.beatrice.hidekobot.objects.commands.SlashCommandImpl;
|
||||||
|
|
||||||
public class SayCommand extends SlashCommandImpl
|
public class SayCommand extends SlashCommandImpl
|
||||||
@@ -22,7 +22,7 @@ public class SayCommand extends SlashCommandImpl
|
|||||||
"The message to send.",
|
"The message to send.",
|
||||||
true,
|
true,
|
||||||
false)
|
false)
|
||||||
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE));
|
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Say.getPermission()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package wtf.beatrice.hidekobot.commands.slash;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.UrbanDictionary;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.SlashCommandImpl;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class UrbanDictionaryCommand extends SlashCommandImpl
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public CommandData getSlashCommandData()
|
||||||
|
{
|
||||||
|
|
||||||
|
return Commands.slash(UrbanDictionary.getCommandLabels().get(0),
|
||||||
|
"Look up a term on Urban Dictionary.")
|
||||||
|
.addOption(OptionType.STRING, "term", "The term to look up", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
|
||||||
|
{
|
||||||
|
event.deferReply().queue();
|
||||||
|
|
||||||
|
// get the term to look up
|
||||||
|
OptionMapping textOption = event.getOption("term");
|
||||||
|
String term = "";
|
||||||
|
if(textOption != null)
|
||||||
|
{
|
||||||
|
term = textOption.getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(textOption == null || term.isEmpty())
|
||||||
|
{
|
||||||
|
event.reply(UrbanDictionary.getNoArgsError())
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String sanitizedTerm = UrbanDictionary.sanitizeArgs(term, false);
|
||||||
|
String url = UrbanDictionary.generateUrl(sanitizedTerm);
|
||||||
|
|
||||||
|
Document doc;
|
||||||
|
|
||||||
|
try {
|
||||||
|
doc = Jsoup.connect(url).get();
|
||||||
|
} catch (IOException e) {
|
||||||
|
event.reply(UrbanDictionary.getTermNotFoundError())
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Elements definitions = doc.getElementsByClass("definition");
|
||||||
|
UrbanDictionary.UrbanSearch search = new UrbanDictionary.UrbanSearch(definitions);
|
||||||
|
MessageEmbed embed = UrbanDictionary.buildEmbed(sanitizedTerm, url, event.getUser(), search, 0);
|
||||||
|
|
||||||
|
// disable next page if we only have one result
|
||||||
|
Button nextPageBtnLocal = UrbanDictionary.getNextPageButton();
|
||||||
|
if(search.getPages() == 1) nextPageBtnLocal = nextPageBtnLocal.asDisabled();
|
||||||
|
|
||||||
|
ActionRow actionRow = ActionRow.of(UrbanDictionary.getPreviousPageButton().asDisabled(),
|
||||||
|
//disabled by default because we're on page 0
|
||||||
|
nextPageBtnLocal,
|
||||||
|
UrbanDictionary.getDeleteButton());
|
||||||
|
event.getHook().editOriginalEmbeds(embed).setComponents(actionRow).queue(message ->
|
||||||
|
UrbanDictionary.track(message, event.getUser(), search, sanitizedTerm));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -81,6 +81,12 @@ public class DatabaseSource
|
|||||||
* | 39402849302 | 39402849302 | 39402849302 | 39402849302 | PRIVATE |
|
* | 39402849302 | 39402849302 | 39402849302 | 39402849302 | PRIVATE |
|
||||||
* --------------------------------------------------------------------------------------------
|
* --------------------------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
* TABLE 3: urban_dictionary
|
||||||
|
* -----------------------------------------------------------------------------------------------------
|
||||||
|
* | message_id | page | meanings | examples | contributors | dates | term |
|
||||||
|
* -----------------------------------------------------------------------------------------------------
|
||||||
|
* | 39402849302 | 0 | base64 | base64 | base64 | base64 | miku |
|
||||||
|
* -----------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//todo: javadocs
|
//todo: javadocs
|
||||||
@@ -104,6 +110,16 @@ public class DatabaseSource
|
|||||||
"channel_type TEXT NOT NULL" + // channel type (PRIVATE, FORUM, ...)
|
"channel_type TEXT NOT NULL" + // channel type (PRIVATE, FORUM, ...)
|
||||||
");");
|
");");
|
||||||
|
|
||||||
|
newTables.add("CREATE TABLE IF NOT EXISTS urban_dictionary (" +
|
||||||
|
"message_id TEXT NOT NULL, " + // message id of the bot's response
|
||||||
|
"page INTEGER NOT NULL," + // page that we are currently on
|
||||||
|
"meanings TEXT NOT NULL," + // list of all meanings, serialized and encoded
|
||||||
|
"examples TEXT NOT NULL, " + // list of all examples, serialized and encoded
|
||||||
|
"contributors TEXT NOT NULL, " + // list of all contributors, serialized and encoded
|
||||||
|
"dates TEXT NOT NULL, " + // list of all submission dates, serialized and encoded
|
||||||
|
"term TEXT NOT NULL" + // the term that was searched
|
||||||
|
");");
|
||||||
|
|
||||||
for(String sql : newTables)
|
for(String sql : newTables)
|
||||||
{
|
{
|
||||||
try (Statement stmt = dbConnection.createStatement()) {
|
try (Statement stmt = dbConnection.createStatement()) {
|
||||||
@@ -301,6 +317,17 @@ public class DatabaseSource
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query = "DELETE FROM urban_dictionary WHERE message_id = ?;";
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, messageId);
|
||||||
|
preparedStatement.execute();
|
||||||
|
} catch (SQLException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,5 +400,220 @@ public class DatabaseSource
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean trackUrban(String meanings, String examples,
|
||||||
|
String contributors, String dates,
|
||||||
|
Message message, String term)
|
||||||
|
{
|
||||||
|
|
||||||
|
String query = "INSERT INTO urban_dictionary " +
|
||||||
|
"(message_id, page, meanings, examples, contributors, dates, term) VALUES " +
|
||||||
|
" (?, ?, ?, ?, ?, ?, ?);";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, message.getId());
|
||||||
|
preparedStatement.setInt(2, 0);
|
||||||
|
preparedStatement.setString(3, meanings);
|
||||||
|
preparedStatement.setString(4, examples);
|
||||||
|
preparedStatement.setString(5, contributors);
|
||||||
|
preparedStatement.setString(6, dates);
|
||||||
|
preparedStatement.setString(7, term);
|
||||||
|
|
||||||
|
preparedStatement.executeUpdate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (SQLException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUrbanPage(String messageId)
|
||||||
|
{
|
||||||
|
String query = "SELECT page " +
|
||||||
|
"FROM urban_dictionary " +
|
||||||
|
"WHERE message_id = ?;";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, messageId);
|
||||||
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
|
if(resultSet.isClosed()) return 0;
|
||||||
|
while(resultSet.next())
|
||||||
|
{
|
||||||
|
return resultSet.getInt("page");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrbanMeanings(String messageId)
|
||||||
|
{
|
||||||
|
String query = "SELECT meanings " +
|
||||||
|
"FROM urban_dictionary " +
|
||||||
|
"WHERE message_id = ?;";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, messageId);
|
||||||
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
|
if(resultSet.isClosed()) return null;
|
||||||
|
while(resultSet.next())
|
||||||
|
{
|
||||||
|
return resultSet.getString("meanings");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrbanExamples(String messageId)
|
||||||
|
{
|
||||||
|
String query = "SELECT examples " +
|
||||||
|
"FROM urban_dictionary " +
|
||||||
|
"WHERE message_id = ?;";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, messageId);
|
||||||
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
|
if(resultSet.isClosed()) return null;
|
||||||
|
while(resultSet.next())
|
||||||
|
{
|
||||||
|
return resultSet.getString("examples");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrbanContributors(String messageId)
|
||||||
|
{
|
||||||
|
String query = "SELECT contributors " +
|
||||||
|
"FROM urban_dictionary " +
|
||||||
|
"WHERE message_id = ?;";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, messageId);
|
||||||
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
|
if(resultSet.isClosed()) return null;
|
||||||
|
while(resultSet.next())
|
||||||
|
{
|
||||||
|
return resultSet.getString("contributors");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrbanDates(String messageId)
|
||||||
|
{
|
||||||
|
String query = "SELECT dates " +
|
||||||
|
"FROM urban_dictionary " +
|
||||||
|
"WHERE message_id = ?;";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, messageId);
|
||||||
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
|
if(resultSet.isClosed()) return null;
|
||||||
|
while(resultSet.next())
|
||||||
|
{
|
||||||
|
return resultSet.getString("dates");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrbanTerm(String messageId)
|
||||||
|
{
|
||||||
|
String query = "SELECT term " +
|
||||||
|
"FROM urban_dictionary " +
|
||||||
|
"WHERE message_id = ?;";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, messageId);
|
||||||
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
|
if(resultSet.isClosed()) return null;
|
||||||
|
while(resultSet.next())
|
||||||
|
{
|
||||||
|
return resultSet.getString("term");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setUrbanPage(String messageId, int page)
|
||||||
|
{
|
||||||
|
String query = "UPDATE urban_dictionary " +
|
||||||
|
"SET page = ? " +
|
||||||
|
"WHERE message_id = ?;";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setInt(1, page);
|
||||||
|
preparedStatement.setString(2, messageId);
|
||||||
|
preparedStatement.executeUpdate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean resetExpiryTimestamp(String messageId)
|
||||||
|
{
|
||||||
|
LocalDateTime expiryTime = LocalDateTime.now().plusSeconds(Cache.getExpiryTimeSeconds());
|
||||||
|
|
||||||
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(Cache.getExpiryTimestampFormat());
|
||||||
|
String expiryTimeFormatted = dateTimeFormatter.format(expiryTime);
|
||||||
|
|
||||||
|
String query = "UPDATE pending_disabled_messages " +
|
||||||
|
"SET expiry_timestamp = ? " +
|
||||||
|
"WHERE message_id = ?;";
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = dbConnection.prepareStatement(query))
|
||||||
|
{
|
||||||
|
preparedStatement.setString(1, expiryTimeFormatted);
|
||||||
|
preparedStatement.setString(2, messageId);
|
||||||
|
preparedStatement.executeUpdate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ package wtf.beatrice.hidekobot.listeners;
|
|||||||
|
|
||||||
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||||
import wtf.beatrice.hidekobot.commands.base.ClearChat;
|
|
||||||
import wtf.beatrice.hidekobot.commands.base.CoinFlip;
|
import wtf.beatrice.hidekobot.commands.base.CoinFlip;
|
||||||
|
import wtf.beatrice.hidekobot.commands.base.UrbanDictionary;
|
||||||
|
import wtf.beatrice.hidekobot.util.CommandUtil;
|
||||||
|
|
||||||
public class ButtonInteractionListener extends ListenerAdapter
|
public class ButtonInteractionListener extends ListenerAdapter
|
||||||
{
|
{
|
||||||
@@ -17,8 +18,12 @@ public class ButtonInteractionListener extends ListenerAdapter
|
|||||||
// coinflip
|
// coinflip
|
||||||
case "coinflip_reflip" -> CoinFlip.buttonReFlip(event);
|
case "coinflip_reflip" -> CoinFlip.buttonReFlip(event);
|
||||||
|
|
||||||
// clearchat command
|
// generic dismiss button
|
||||||
case "clear_dismiss" -> ClearChat.dismissMessage(event);
|
case "generic_dismiss" -> CommandUtil.delete(event);
|
||||||
|
|
||||||
|
// urban dictionary navigation
|
||||||
|
case "urban_nextpage" -> UrbanDictionary.changePage(event, UrbanDictionary.ChangeType.NEXT);
|
||||||
|
case "urban_previouspage" -> UrbanDictionary.changePage(event, UrbanDictionary.ChangeType.PREVIOUS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,13 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
|
|||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
|
import wtf.beatrice.hidekobot.objects.commands.CommandCategory;
|
||||||
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
|
||||||
import wtf.beatrice.hidekobot.objects.comparators.MessageCommandAliasesComparator;
|
import wtf.beatrice.hidekobot.objects.comparators.MessageCommandAliasesComparator;
|
||||||
import wtf.beatrice.hidekobot.util.Logger;
|
import wtf.beatrice.hidekobot.util.Logger;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
public class MessageCommandListener extends ListenerAdapter
|
public class MessageCommandListener extends ListenerAdapter
|
||||||
{
|
{
|
||||||
@@ -23,6 +22,10 @@ public class MessageCommandListener extends ListenerAdapter
|
|||||||
private final TreeMap<LinkedList<String>, MessageCommand> registeredCommands =
|
private final TreeMap<LinkedList<String>, MessageCommand> registeredCommands =
|
||||||
new TreeMap<LinkedList<String>, MessageCommand>(new MessageCommandAliasesComparator());
|
new TreeMap<LinkedList<String>, MessageCommand>(new MessageCommandAliasesComparator());
|
||||||
|
|
||||||
|
// map commands and their categories.
|
||||||
|
// this is not strictly needed but it's better to have it so we avoid looping every time we need to check the cat.
|
||||||
|
LinkedHashMap<CommandCategory, LinkedList<MessageCommand>> commandCategories = new LinkedHashMap<>();
|
||||||
|
|
||||||
private final String commandRegex = "(?i)^(hideko|hde)\\b";
|
private final String commandRegex = "(?i)^(hideko|hde)\\b";
|
||||||
// (?i) -> case insensitive flag
|
// (?i) -> case insensitive flag
|
||||||
// ^ -> start of string (not in middle of a sentence)
|
// ^ -> start of string (not in middle of a sentence)
|
||||||
@@ -57,10 +60,14 @@ public class MessageCommandListener extends ListenerAdapter
|
|||||||
@Override
|
@Override
|
||||||
public void onMessageReceived(@NotNull MessageReceivedEvent event)
|
public void onMessageReceived(@NotNull MessageReceivedEvent event)
|
||||||
{
|
{
|
||||||
String eventMessage = event.getMessage().getContentDisplay();
|
// check if a bot is sending this message, and ignore it
|
||||||
|
if(event.getAuthor().isBot()) return;
|
||||||
|
|
||||||
|
// warning: we are getting the RAW value of the message content, not the DISPLAY value!
|
||||||
|
String eventMessage = event.getMessage().getContentRaw();
|
||||||
|
|
||||||
// check if the sent message matches the bot activation regex (prefix, name, ...)
|
// check if the sent message matches the bot activation regex (prefix, name, ...)
|
||||||
if(!eventMessage.toLowerCase().matches(commandRegex + ".*"))
|
if(!eventMessage.toLowerCase().matches(commandRegex + "((.|\\n)*)"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// generate args from the string
|
// generate args from the string
|
||||||
@@ -74,7 +81,9 @@ public class MessageCommandListener extends ListenerAdapter
|
|||||||
// it will be the whole text as a single element.
|
// it will be the whole text as a single element.
|
||||||
if(argsString.isEmpty())
|
if(argsString.isEmpty())
|
||||||
{
|
{
|
||||||
event.getMessage().reply("Hello there! ✨").queue();
|
event.getMessage()
|
||||||
|
.reply("Hello there! ✨ Type `" + Cache.getBotPrefix() + " help` to get started!")
|
||||||
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +96,11 @@ public class MessageCommandListener extends ListenerAdapter
|
|||||||
|
|
||||||
if(commandObject == null)
|
if(commandObject == null)
|
||||||
{
|
{
|
||||||
|
/* temporarily disabled because when people talk about the bot, it replies with this spammy message.
|
||||||
|
|
||||||
event.getMessage().reply("Unrecognized command: `" + commandLabel + "`!").queue(); // todo prettier
|
event.getMessage().reply("Unrecognized command: `" + commandLabel + "`!").queue(); // todo prettier
|
||||||
|
|
||||||
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +133,9 @@ public class MessageCommandListener extends ListenerAdapter
|
|||||||
String[] commandArgs;
|
String[] commandArgs;
|
||||||
if(commandObject.passRawArgs())
|
if(commandObject.passRawArgs())
|
||||||
{
|
{
|
||||||
|
|
||||||
// remove first argument, which is the command label
|
// remove first argument, which is the command label
|
||||||
argsString = argsString.replaceAll("^[\\S]+\\s+", "");
|
argsString = argsString.replaceAll("^[\\S]+\\s*", "");
|
||||||
// pass all other arguments as a single argument as the first array element
|
// pass all other arguments as a single argument as the first array element
|
||||||
commandArgs = new String[]{argsString};
|
commandArgs = new String[]{argsString};
|
||||||
}
|
}
|
||||||
|
|||||||
45
src/main/java/wtf/beatrice/hidekobot/objects/Dice.java
Normal file
45
src/main/java/wtf/beatrice/hidekobot/objects/Dice.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package wtf.beatrice.hidekobot.objects;
|
||||||
|
|
||||||
|
import wtf.beatrice.hidekobot.util.RandomUtil;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Dice
|
||||||
|
{
|
||||||
|
private final int sides;
|
||||||
|
private int value = 0;
|
||||||
|
private final UUID uuid;
|
||||||
|
|
||||||
|
public Dice(int sides)
|
||||||
|
{
|
||||||
|
this.sides = sides;
|
||||||
|
this.uuid = UUID.randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dice(Dice old)
|
||||||
|
{
|
||||||
|
this.sides = old.sides;
|
||||||
|
this.value = old.value;
|
||||||
|
this.uuid = UUID.randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSides()
|
||||||
|
{
|
||||||
|
return sides;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void roll()
|
||||||
|
{
|
||||||
|
value = RandomUtil.getRandomNumber(1, sides);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUUID()
|
||||||
|
{
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package wtf.beatrice.hidekobot.objects.commands;
|
||||||
|
|
||||||
|
public enum CommandCategory
|
||||||
|
{
|
||||||
|
MODERATION("️\uD83D\uDC40"),
|
||||||
|
FUN("\uD83C\uDFB2"),
|
||||||
|
TOOLS("\uD83D\uDEE0"),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
private String emoji;
|
||||||
|
CommandCategory(String emoji)
|
||||||
|
{
|
||||||
|
this.emoji = emoji;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmoji() { return emoji; }
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package wtf.beatrice.hidekobot.objects.commands;
|
|||||||
|
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -39,6 +40,31 @@ public interface MessageCommand
|
|||||||
*/
|
*/
|
||||||
boolean passRawArgs();
|
boolean passRawArgs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Say what category this command belongs to.
|
||||||
|
*
|
||||||
|
* @return the command category.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
CommandCategory getCategory();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Say what this command does.
|
||||||
|
*
|
||||||
|
* @return a String explaining what this command does.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
String getDescription();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Say how people should use this command.
|
||||||
|
*
|
||||||
|
* @return a String explaining how to use the command, excluding the bot prefix and command name. Null if no parameter is needed
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getUsage();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the command logic by parsing the event and replying accordingly.
|
* Run the command logic by parsing the event and replying accordingly.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,21 +1,48 @@
|
|||||||
package wtf.beatrice.hidekobot.util;
|
package wtf.beatrice.hidekobot.util;
|
||||||
|
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
import net.dv8tion.jda.api.interactions.commands.Command;
|
import net.dv8tion.jda.api.interactions.commands.Command;
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||||
import wtf.beatrice.hidekobot.Cache;
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
import wtf.beatrice.hidekobot.HidekoBot;
|
import wtf.beatrice.hidekobot.HidekoBot;
|
||||||
import wtf.beatrice.hidekobot.listeners.MessageCommandListener;
|
|
||||||
import wtf.beatrice.hidekobot.objects.commands.SlashCommand;
|
import wtf.beatrice.hidekobot.objects.commands.SlashCommand;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SlashCommandUtil
|
public class CommandUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final Logger logger = new Logger(MessageCommandListener.class);
|
private static final Logger logger = new Logger(CommandUtil.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to delete a message when a user clicks the "delete" button attached to that message.
|
||||||
|
* This will check in the database if that user ran the command originally.
|
||||||
|
*
|
||||||
|
* @param event the button interaction event.
|
||||||
|
*/
|
||||||
|
public static void delete(ButtonInteractionEvent event)
|
||||||
|
{
|
||||||
|
// check if the user interacting is the same one who ran the command
|
||||||
|
if (!(Cache.getDatabaseSource().isUserTrackedFor(event.getUser().getId(), event.getMessageId()))) {
|
||||||
|
event.reply("❌ You did not run this command!").setEphemeral(true).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the message
|
||||||
|
event.getInteraction().getMessage().delete().queue();
|
||||||
|
// no need to manually untrack it from database, it will be purged on the next planned check.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to update slash commands registered on Discord's side.
|
||||||
|
* It runs automatically every time the bot starts, but only updates the commands in case differences
|
||||||
|
* are found, unless forced.
|
||||||
|
*
|
||||||
|
* @param force a boolean specifying if the update should be forced even if no differences were found.
|
||||||
|
*/
|
||||||
public static void updateSlashCommands(boolean force)
|
public static void updateSlashCommands(boolean force)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package wtf.beatrice.hidekobot.util;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.SerializationException;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SerializationUtil
|
||||||
|
{
|
||||||
|
|
||||||
|
public static String serializeBase64(List dataList) {
|
||||||
|
|
||||||
|
try (ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||||
|
ObjectOutputStream so = new ObjectOutputStream(bo)) {
|
||||||
|
so.writeObject(dataList);
|
||||||
|
so.flush();
|
||||||
|
return Base64.getEncoder().encodeToString(bo.toByteArray());
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new SerializationException("Error during serialization", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LinkedList deserializeBase64(String dataStr) {
|
||||||
|
|
||||||
|
byte[] b = Base64.getDecoder().decode(dataStr);
|
||||||
|
ByteArrayInputStream bi = new ByteArrayInputStream(b);
|
||||||
|
ObjectInputStream si;
|
||||||
|
try {
|
||||||
|
si = new ObjectInputStream(bi);
|
||||||
|
return LinkedList.class.cast(si.readObject());
|
||||||
|
}
|
||||||
|
catch (IOException | ClassNotFoundException e) {
|
||||||
|
throw new SerializationException("Error during deserialization", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user