diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
index 6f0854a2..71813715 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.md
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -19,4 +19,4 @@ Add any other context or screenshots about the feature request here.
# Checklist:
- [ ] I have checked for similar issues.
-- [ ] This is a feature request, not improvement request, bug report, or security vulnerability report.
\ No newline at end of file
+- [ ] This is a feature request, not an improvement request, bug report, or security vulnerability report.
\ No newline at end of file
diff --git a/README.md b/README.md
index a84df215..7ec4b993 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
A cafe bot for your discord server!
- Explore the docs ยป
+ Explore the Docs ยป
View Demo
@@ -133,8 +133,10 @@ As you can see, this was shown using the command `/help order`. It shows each pa
* `feature-request` - Request a bot feature.
* `generate-code` - Generate a random 32-digit long code!
* `help` - Shows the list of command sections and command list for those sections.
-* `ping` - Show bot information!
+* `info` - Show information about the bot!
+* `ping` - Show technical information about the bot!
* `remove-my-data` - Request to remove your data from the bot!
+* `stats` - Show statistics such as commands run, current servers, and users!
* `support` - Get support for the bot!
* `user-info` - Get user information about someone.
##### 2. **CAFE**
@@ -145,11 +147,14 @@ As you can see, this was shown using the command `/help order`. It shows each pa
* `serve` - Get beanCoins! Essentially you run this command by doing `/serve (dictionary word)`! This must be an english word. The longer the word, the more money you get. However, the more popular the word is, the less money you will get for it.
##### 3. **FUN**
* `avatar` - Get yours or someone else's avatar image!
+* `banner` - Get yours or someone else's profile banner!
* `birthday` - Add, change, or remove your birthday! Even get someone else's birthday!
* `coffee-meme` - Get a coffee meme!
* `counting-statistics` - Get counting information for your server!
* `joke` - Send a joke in the current channel. (SFW)
* `meme` - Send a meme in the current channel. (SFW)
+* `rate` - Rate the percentages of someone! (*somewhat* NSFW)
+* `snipe` - Snipe a recently deleted message! (30 Seconds)
* `tea-meme` - Get a tea meme!
##### 4. **GAMES**
* `8-ball` - Ask a yes or no question!
diff --git a/src/main/java/com/beanbeanjuice/Bot.java b/src/main/java/com/beanbeanjuice/Bot.java
index 6652c3ba..7676d2d5 100644
--- a/src/main/java/com/beanbeanjuice/Bot.java
+++ b/src/main/java/com/beanbeanjuice/Bot.java
@@ -100,6 +100,7 @@ public Bot() throws LoginException, InterruptedException {
commandHandler,
new ServerListener(), // Listening for Guild Joins/Leaves
new MessageListener(), // Listening for specific messages
+ new MessageDeleteListener(), // Listening for message deletions
new WelcomeListener(), // Listening for user joins for a guild.
new AIResponseListener(), // Listening for messages.
new VoiceChatRoleBindListener(), // Listening for voice joins/leaves
@@ -120,7 +121,7 @@ public Bot() throws LoginException, InterruptedException {
VoiceChatRoleBindHandler.start();
bot.getPresence().setStatus(OnlineStatus.ONLINE);
- updateGuildPresence();
+ Helper.startBioUpdateTimer();
logger.log(Bot.class, LogLevel.OKAY, "The bot is online!");
new GitHubUpdateHelper().start(); // Notify Guilds of Update
@@ -171,11 +172,4 @@ public static CommandHandler getCommandHandler() {
return commandHandler;
}
- /**
- * Updates the presence for the {@link JDA}.
- */
- public static void updateGuildPresence() {
- bot.getPresence().setActivity(Activity.playing("/help | cafeBot " + BOT_VERSION + " - Currently in " + bot.getGuilds().size() + " servers!"));
- }
-
}
diff --git a/src/main/java/com/beanbeanjuice/command/fun/AvatarCommand.java b/src/main/java/com/beanbeanjuice/command/fun/AvatarCommand.java
index 964c51b2..8f701b73 100644
--- a/src/main/java/com/beanbeanjuice/command/fun/AvatarCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/fun/AvatarCommand.java
@@ -33,7 +33,7 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
@NotNull
private MessageEmbed avatarEmbed(@NotNull User user) {
return new EmbedBuilder()
- .setTitle(user.getName() + "'s Avatar", user.getAvatarUrl())
+ .setTitle(user.getName() + "'s Avatar")
.setImage(user.getAvatarUrl() + "?size=512")
.setColor(Helper.getRandomColor())
.build();
diff --git a/src/main/java/com/beanbeanjuice/command/fun/BannerCommand.java b/src/main/java/com/beanbeanjuice/command/fun/BannerCommand.java
new file mode 100644
index 00000000..1eb85c29
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/fun/BannerCommand.java
@@ -0,0 +1,126 @@
+package com.beanbeanjuice.command.fun;
+
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ICommand;
+import com.beanbeanjuice.utility.helper.Helper;
+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.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
+import org.jetbrains.annotations.NotNull;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * An {@link ICommand} used to get the banner of a {@link net.dv8tion.jda.api.entities.User User}.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class BannerCommand implements ICommand {
+
+ private final String filename = "banner_image.jpg";
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ User user = event.getUser();
+ if (event.getOption("user") != null)
+ user = event.getOption("user").getAsUser();
+
+ String username = user.getName();
+ String avatarURL = user.getAvatarUrl();
+
+ user.retrieveProfile().queue(
+ (profile) -> {
+ if (profile.getBannerUrl() != null) {
+ event.getHook().sendMessageEmbeds(bannerEmbed(username, avatarURL, profile)).queue();
+ } else {
+ File file = new File(filename);
+ event.getHook().sendMessageEmbeds(bannerEmbed(username, avatarURL, profile))
+ .addFile(file, filename).queue((message) -> {
+ file.delete(); // Finally delete the file once the message is sent.
+ });
+ }
+ },
+ (failure) -> {
+ event.getHook().sendMessageEmbeds(Helper.errorEmbed(
+ "Error Getting Banner",
+ "There was an error getting " + username + "'s banner. " +
+ "Please try again later."
+ )).queue();
+ });
+ }
+
+ @NotNull
+ private MessageEmbed bannerEmbed(@NotNull String username, @NotNull String avatarURL, @NotNull User.Profile profile) {
+ EmbedBuilder embedBuilder = new EmbedBuilder()
+ .setColor(profile.getAccentColor())
+ .setAuthor(username + "'s Banner", null, avatarURL);
+
+ if (profile.getBannerUrl() != null) {
+ embedBuilder.setImage(profile.getBannerUrl() + "?size=600");
+ } else {
+ int width = 600, height = 240;
+
+ // Creating the image in code.
+ BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ Graphics2D graphics2D = bufferedImage.createGraphics();
+
+ // Setting the colour and filling it.
+ graphics2D.setColor(profile.getAccentColor());
+ graphics2D.fillRect(0, 0, width, height);
+
+ // Clearing up resources.
+ graphics2D.dispose();
+
+ // Creating the file, and writing the file.
+ File file = new File(filename);
+ try {
+ ImageIO.write(bufferedImage, "jpg", file);
+ embedBuilder.setImage("attachment://" + filename);
+ } catch (IOException ignored) { }
+ }
+
+ return embedBuilder.build();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Get your or another user's banner!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/banner` or `/banner @beanbeanjuice`";
+ }
+
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.USER, "user", "The user you want to get the banner of.", false));
+ return options;
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.FUN;
+ }
+
+ @NotNull
+ @Override
+ public Boolean allowDM() {
+ return true;
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/fun/SnipeCommand.java b/src/main/java/com/beanbeanjuice/command/fun/SnipeCommand.java
new file mode 100644
index 00000000..5716f19f
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/fun/SnipeCommand.java
@@ -0,0 +1,52 @@
+package com.beanbeanjuice.command.fun;
+
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ICommand;
+import com.beanbeanjuice.utility.handler.snipe.SnipeHandler;
+import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * An {@link ICommand} to use with the {@link com.beanbeanjuice.utility.handler.snipe.SnipeHandler SnipeHandler}.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class SnipeCommand implements ICommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ MessageEmbed embed = SnipeHandler.getLatestSnipe(event.getTextChannel().getId());
+
+ if (embed == null) {
+ event.getHook().sendMessageEmbeds(Helper.errorEmbed(
+ "No Snipe",
+ "There was nothing to snipe!"
+ )).queue();
+ return;
+ }
+
+ event.getHook().sendMessageEmbeds(embed).queue();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Snipe a message in this channel!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/snipe`";
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.FUN;
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/fun/rate/RateCommand.java b/src/main/java/com/beanbeanjuice/command/fun/rate/RateCommand.java
new file mode 100644
index 00000000..12dc40ae
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/fun/rate/RateCommand.java
@@ -0,0 +1,58 @@
+package com.beanbeanjuice.command.fun.rate;
+
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ICommand;
+import com.beanbeanjuice.utility.command.ISubCommand;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+/**
+ * An {@link ICommand} used to rate people.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class RateCommand implements ICommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) { }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Rate someone!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/rate simp` or `/rate insane @beanbeanjuice`";
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.FUN;
+ }
+
+ @NotNull
+ @Override
+ public ArrayList getSubCommands() {
+ ArrayList subCommands = new ArrayList<>();
+ subCommands.add(new RateSimpSubCommand());
+ subCommands.add(new RateGaySubCommand());
+ subCommands.add(new RateSmartSubCommand());
+ subCommands.add(new RatePoorSubCommand());
+ subCommands.add(new RateInsaneSubCommand());
+ return subCommands;
+ }
+
+ @NotNull
+ @Override
+ public Boolean allowDM() {
+ return true;
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/fun/rate/RateGaySubCommand.java b/src/main/java/com/beanbeanjuice/command/fun/rate/RateGaySubCommand.java
new file mode 100644
index 00000000..fc2f2b2f
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/fun/rate/RateGaySubCommand.java
@@ -0,0 +1,66 @@
+package com.beanbeanjuice.command.fun.rate;
+
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ISubCommand;
+import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+/**
+ * An {@link ISubCommand} used to rate someone's gay percentage.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class RateGaySubCommand implements ISubCommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ User user = event.getUser();
+ if (event.getOption("user") != null)
+ user = event.getOption("user").getAsUser();
+
+ event.getHook().sendMessageEmbeds(Helper.smallAuthorEmbed(
+ "Gay Rating", null, user.getAvatarUrl(),
+ "The gay rating is `" + Helper.getRandomNumber(0, 101) + "`%! ๐ณ๏ธโ๐" // Gay Pride Flag
+ )).queue();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Rate someone's gay percentage!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/rate gay` or `/rate gay @beanbeanjuice`";
+ }
+
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.USER, "user", "THe person to rate!", false));
+ return options;
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.FUN;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "gay";
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/fun/rate/RateInsaneSubCommand.java b/src/main/java/com/beanbeanjuice/command/fun/rate/RateInsaneSubCommand.java
new file mode 100644
index 00000000..d08e3f26
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/fun/rate/RateInsaneSubCommand.java
@@ -0,0 +1,66 @@
+package com.beanbeanjuice.command.fun.rate;
+
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ISubCommand;
+import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+/**
+ * An {@link ISubCommand} used to rate how insane someone is!
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class RateInsaneSubCommand implements ISubCommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ User user = event.getUser();
+ if (event.getOption("user") != null)
+ user = event.getOption("user").getAsUser();
+
+ event.getHook().sendMessageEmbeds(Helper.smallAuthorEmbed(
+ "Insane Rating", null, user.getAvatarUrl(),
+ "The insane rating is `" + Helper.getRandomNumber(0, 101) + "`%! "
+ )).queue();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Rate how insane someone is!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/rate insane` or `/rate insane @beanbeanjuice`";
+ }
+
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.USER, "user", "THe person to rate!", false));
+ return options;
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.FUN;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "insane";
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/fun/rate/RatePoorSubCommand.java b/src/main/java/com/beanbeanjuice/command/fun/rate/RatePoorSubCommand.java
new file mode 100644
index 00000000..a6e780fd
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/fun/rate/RatePoorSubCommand.java
@@ -0,0 +1,66 @@
+package com.beanbeanjuice.command.fun.rate;
+
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ISubCommand;
+import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+/**
+ * An {@link ISubCommand} used to rate how poor someone is!
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class RatePoorSubCommand implements ISubCommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ User user = event.getUser();
+ if (event.getOption("user") != null)
+ user = event.getOption("user").getAsUser();
+
+ event.getHook().sendMessageEmbeds(Helper.smallAuthorEmbed(
+ "Poor Rating", null, user.getAvatarUrl(),
+ "The poor rating is `" + Helper.getRandomNumber(0, 101) + "`%! <:HUH:996901946344607764>"
+ )).queue();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Rate how poor someone is!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/rate poor` or `/rate poor @beanbeanjuice`";
+ }
+
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.USER, "user", "THe person to rate!", false));
+ return options;
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.FUN;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "poor";
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/fun/rate/RateSimpSubCommand.java b/src/main/java/com/beanbeanjuice/command/fun/rate/RateSimpSubCommand.java
new file mode 100644
index 00000000..b03312d0
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/fun/rate/RateSimpSubCommand.java
@@ -0,0 +1,66 @@
+package com.beanbeanjuice.command.fun.rate;
+
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ISubCommand;
+import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+/**
+ * An {@link ISubCommand} used to rate someone's simp level.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class RateSimpSubCommand implements ISubCommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ User user = event.getUser();
+ if (event.getOption("user") != null)
+ user = event.getOption("user").getAsUser();
+
+ event.getHook().sendMessageEmbeds(Helper.smallAuthorEmbed(
+ "Simp Rating", null, user.getAvatarUrl(),
+ "The simp rating is `" + Helper.getRandomNumber(0, 101) + "`%!"
+ )).queue();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Rate someone's simp level!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/rate simp` or `/rate simp @beanbeanjuice`";
+ }
+
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.USER, "user", "THe person to rate!", false));
+ return options;
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.FUN;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "simp";
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/fun/rate/RateSmartSubCommand.java b/src/main/java/com/beanbeanjuice/command/fun/rate/RateSmartSubCommand.java
new file mode 100644
index 00000000..c66edf55
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/fun/rate/RateSmartSubCommand.java
@@ -0,0 +1,66 @@
+package com.beanbeanjuice.command.fun.rate;
+
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ISubCommand;
+import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+/**
+ * An {@link ISubCommand} used to rate how smart someone is.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class RateSmartSubCommand implements ISubCommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ User user = event.getUser();
+ if (event.getOption("user") != null)
+ user = event.getOption("user").getAsUser();
+
+ event.getHook().sendMessageEmbeds(Helper.smallAuthorEmbed(
+ "Smart Rating", null, user.getAvatarUrl(),
+ "The smart rating is `" + Helper.getRandomNumber(0, 101) + "`%! <:smartPeepo:1000248538376196280>"
+ )).queue();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Rate how smart someone is!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/rate smart` or `/rate smart @beanbeanjuice`";
+ }
+
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.USER, "user", "THe person to rate!", false));
+ return options;
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.FUN;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "smart";
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/generic/BotUpvoteCommand.java b/src/main/java/com/beanbeanjuice/command/generic/BotUpvoteCommand.java
index 30ff1b0a..6be30aa4 100644
--- a/src/main/java/com/beanbeanjuice/command/generic/BotUpvoteCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/generic/BotUpvoteCommand.java
@@ -3,20 +3,39 @@
import com.beanbeanjuice.utility.command.CommandCategory;
import com.beanbeanjuice.utility.command.ICommand;
import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
+/**
+ * An {@link ICommand} used to upvote the bot.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
public class BotUpvoteCommand implements ICommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
- event.getHook().sendMessageEmbeds(Helper.successEmbed(
- "Bot Upvote",
- """
- If you want to show your support for the bot, please click the links below! Please click the links below
+ event.getHook().sendMessageEmbeds(Helper.errorEmbed(
+ "Voting List",
+ "If you want to show support for the bot, click the buttons below! " +
+ "Soon, there will be a feature where you can get perks for up-voting the bot. " +
+ "Any and all support is welcome!"
+ )).addActionRow(getButtons()).queue();
+ }
- **Link 1**: [top.gg](https://top.gg/bot/787162619504492554)."""
- )).queue();
+ @NotNull
+ private ArrayList getButtons() {
+ ArrayList buttons = new ArrayList<>();
+ buttons.add(Button.link("https://top.gg/bot/787162619504492554/vote", "Top.GG")
+ .withEmoji(Emoji.fromFormatted("")));
+ buttons.add(Button.link("https://discordbotlist.com/bots/cafebot-8422/upvote", "Discord Bot List")
+ .withEmoji(Emoji.fromFormatted("")));
+ return buttons;
}
@NotNull
diff --git a/src/main/java/com/beanbeanjuice/command/generic/InfoCommand.java b/src/main/java/com/beanbeanjuice/command/generic/InfoCommand.java
new file mode 100644
index 00000000..677cf2d7
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/generic/InfoCommand.java
@@ -0,0 +1,60 @@
+package com.beanbeanjuice.command.generic;
+
+import com.beanbeanjuice.Bot;
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ICommand;
+import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * An {@link ICommand} used to get info on the {@link net.dv8tion.jda.api.JDA bot}.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class InfoCommand implements ICommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ event.getHook().sendMessageEmbeds(infoEmbed()).queue();
+ }
+
+ @NotNull
+ private MessageEmbed infoEmbed() {
+ return new EmbedBuilder()
+ .setColor(Helper.getRandomColor())
+ .setAuthor("Bot Information", null, Bot.getBot().getSelfUser().getAvatarUrl())
+ .addField("โ Commands Run", "```" + Bot.commandsRun + "```", true)
+ .addField(" Creator", "```beanbeanjuice#4595```", true)
+ .addField("<:html:1000241652444692530> Frameworks", "Built With: [Discord JDA](https://github.com/DV8FromTheWorld/JDA), " +
+ "[Twitch4J](https://github.com/twitch4j/twitch4j), [KawaiiAPI](https://kawaii.red/), " +
+ "and [Maven](https://maven.apache.org/)!", true)
+ .addField(" About Me", "Hello! I'm cafeBot, a general/" +
+ "multipurpose bot that is used to do a multitude of things! You can do `/help` to see the " +
+ "list of my commands. I hope you enjoy me!", false)
+ .setFooter("If you want to upvote me, please do so with /bot-upvote!")
+ .build();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Get the bot's information!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/info`";
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.GENERIC;
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/generic/StatsCommand.java b/src/main/java/com/beanbeanjuice/command/generic/StatsCommand.java
new file mode 100644
index 00000000..2f257f41
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/command/generic/StatsCommand.java
@@ -0,0 +1,61 @@
+package com.beanbeanjuice.command.generic;
+
+import com.beanbeanjuice.Bot;
+import com.beanbeanjuice.utility.command.CommandCategory;
+import com.beanbeanjuice.utility.command.ICommand;
+import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * An {@link ICommand} used to get stats for the bot.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class StatsCommand implements ICommand {
+
+ @Override
+ public void handle(@NotNull SlashCommandInteractionEvent event) {
+ event.getHook().sendMessageEmbeds(statsEmbed()).queue();
+ }
+
+ private MessageEmbed statsEmbed() {
+ return new EmbedBuilder()
+ .setColor(Helper.getRandomColor())
+ .setAuthor("Bot Statistics", null, Bot.getBot().getSelfUser().getAvatarUrl())
+ .addField(" Total Text Channels", "```" + Helper.getTotalChannels() + "```", true)
+ .addField("<:smartPeepo:1000248538376196280> Total Servers", "```" + Helper.getTotalServers() + "```", true)
+ .addField("โ Total Commands Run", "```" + Bot.commandsRun + "```", true)
+ .addField(" Total Users", "```" + Helper.getTotalUsers() + "```", true)
+ .setFooter("If you are enjoying this bot, please consider using /bot-upvote!")
+ .build();
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Get stats regarding the bot!";
+ }
+
+ @NotNull
+ @Override
+ public String exampleUsage() {
+ return "`/stats`";
+ }
+
+ @NotNull
+ @Override
+ public CommandCategory getCategoryType() {
+ return CommandCategory.GENERIC;
+ }
+
+ @NotNull
+ @Override
+ public Boolean allowDM() {
+ return true;
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/command/settings/birthday/SetBirthdayChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/birthday/SetBirthdayChannelSubCommand.java
index 79a74b11..ba04275b 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/birthday/SetBirthdayChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/birthday/SetBirthdayChannelSubCommand.java
@@ -23,11 +23,17 @@ public class SetBirthdayChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
- TextChannel textChannel = event.getTextChannel();
+ TextChannel channel = event.getTextChannel();
if (event.getOption("birthday_channel") != null)
- textChannel = event.getOption("birthday_channel").getAsTextChannel();
+ channel = event.getOption("birthday_channel").getAsTextChannel();
- if (GuildHandler.getCustomGuild(event.getGuild()).setBirthdayChannelID(textChannel.getId())) {
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(channel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
+
+ if (GuildHandler.getCustomGuild(event.getGuild()).setBirthdayChannelID(channel.getId())) {
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Updated Birthday Channel",
"This channel has been set to an active birthday channel! Any user who has a birthday " +
diff --git a/src/main/java/com/beanbeanjuice/command/settings/counting/SetCountingChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/counting/SetCountingChannelSubCommand.java
index 0b89cc9e..9e2cfdc6 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/counting/SetCountingChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/counting/SetCountingChannelSubCommand.java
@@ -8,9 +8,15 @@
import com.beanbeanjuice.cafeapi.exception.api.AuthorizationException;
import com.beanbeanjuice.cafeapi.exception.api.ConflictException;
import com.beanbeanjuice.cafeapi.exception.api.ResponseException;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
/**
* An {@link ISubCommand} used to set the counting {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}
* for a specified {@link net.dv8tion.jda.api.entities.Guild Guild}.
@@ -21,9 +27,18 @@ public class SetCountingChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
+ TextChannel channel = event.getTextChannel();
+ if (event.getOption("counting_channel") != null)
+ channel = event.getOption("counting_channel").getAsTextChannel();
+
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(channel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
// Attempt to add the counting channel to the database.
- if (GuildHandler.getCustomGuild(event.getGuild()).setCountingChannel(event.getChannel().getId())) {
+ if (GuildHandler.getCustomGuild(event.getGuild()).setCountingChannel(channel.getId())) {
// Send a success embed if it worked.
event.getHook().sendMessageEmbeds(Helper.successEmbed(
@@ -50,6 +65,15 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
event.getHook().sendMessageEmbeds(Helper.sqlServerError()).queue();
}
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.CHANNEL, "counting_channel", "The text channel set as a counting channel.", false)
+ .setChannelTypes(ChannelType.TEXT));
+ return options;
+ }
+
@NotNull
@Override
public String getDescription() {
diff --git a/src/main/java/com/beanbeanjuice/command/settings/daily/SetDailyChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/daily/SetDailyChannelSubCommand.java
index 0840b575..2192e419 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/daily/SetDailyChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/daily/SetDailyChannelSubCommand.java
@@ -2,13 +2,16 @@
import com.beanbeanjuice.utility.command.CommandCategory;
import com.beanbeanjuice.utility.command.ISubCommand;
-import com.beanbeanjuice.utility.handler.guild.CustomChannel;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.ArrayList;
/**
* An {@link ISubCommand} used to set the daily {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}
@@ -20,16 +23,12 @@ public class SetDailyChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
- AtomicBoolean alreadySet = new AtomicBoolean(false);
- GuildHandler.getCustomGuild(event.getGuild()).getCustomChannelIDs().forEach((customChannel, channelID) -> {
- if (!customChannel.equals(CustomChannel.DAILY)) {
- if (channelID.equals(event.getChannel().getId())) {
- alreadySet.set(true);
- }
- }
- });
+ TextChannel channel = event.getTextChannel();
- if (alreadySet.get()) {
+ if (event.getOption("daily_channel") != null)
+ channel = event.getOption("daily_channel").getAsTextChannel();
+
+ if (GuildHandler.getCustomGuild(event.getGuild()).isCustomChannel(channel.getId())) {
event.getHook().sendMessageEmbeds(Helper.errorEmbed("Channel Already Set",
"This current channel is already set to something. For a list of channels you are already using with this bot, do `/" +
"list-custom-channels`")).queue();
@@ -49,6 +48,15 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
event.getHook().sendMessageEmbeds(Helper.sqlServerError()).queue();
}
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.CHANNEL, "daily_channel", "The text channel to reset daily.", false)
+ .setChannelTypes(ChannelType.TEXT));
+ return options;
+ }
+
@NotNull
@Override
public String getDescription() {
diff --git a/src/main/java/com/beanbeanjuice/command/settings/logging/SetLogChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/logging/SetLogChannelSubCommand.java
index b08786c4..3cd078b1 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/logging/SetLogChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/logging/SetLogChannelSubCommand.java
@@ -4,9 +4,15 @@
import com.beanbeanjuice.utility.command.ISubCommand;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
/**
* An {@link ISubCommand} used to set the log {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}
* for the specified {@link net.dv8tion.jda.api.entities.Guild Guild}.
@@ -17,7 +23,17 @@ public class SetLogChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
- if (GuildHandler.getCustomGuild(event.getGuild()).setLogChannelID(event.getChannel().getId())) {
+ TextChannel channel = event.getTextChannel();
+ if (event.getOption("log_channel") != null)
+ channel = event.getOption("log_channel").getAsTextChannel();
+
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(channel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
+
+ if (GuildHandler.getCustomGuild(event.getGuild()).setLogChannelID(channel.getId())) {
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Set Log Channel",
"The current channel has been set to a `log` channel!"
@@ -28,6 +44,15 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
event.getHook().sendMessageEmbeds(Helper.sqlServerError()).queue();
}
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.CHANNEL, "log_channel", "The text channel to send logging information to.", false)
+ .setChannelTypes(ChannelType.TEXT));
+ return options;
+ }
+
@NotNull
@Override
public String getDescription() {
diff --git a/src/main/java/com/beanbeanjuice/command/settings/poll/SetPollChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/poll/SetPollChannelSubCommand.java
index 2fb2fa34..ed8a89ff 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/poll/SetPollChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/poll/SetPollChannelSubCommand.java
@@ -5,9 +5,15 @@
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
import com.beanbeanjuice.utility.section.moderation.poll.Poll;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
/**
* An {@link ISubCommand} used to set the {@link Poll Poll} {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}.
*
@@ -17,9 +23,18 @@ public class SetPollChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
+ TextChannel channel = event.getTextChannel();
+ if (event.getOption("poll_channel") != null)
+ channel = event.getOption("poll_channel").getAsTextChannel();
+
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(channel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
// Makes sure the poll channel has been added to the database.
- if (GuildHandler.getCustomGuild(event.getGuild()).setPollChannel(event.getChannel().getId())) {
+ if (GuildHandler.getCustomGuild(event.getGuild()).setPollChannel(channel.getId())) {
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Set Poll Channel",
"The current channel has been set to a `poll` channel!"
@@ -30,6 +45,15 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
event.getHook().sendMessageEmbeds(Helper.sqlServerError()).queue();
}
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.CHANNEL, "poll_channel", "The text channel to send poll information to.", false)
+ .setChannelTypes(ChannelType.TEXT));
+ return options;
+ }
+
@NotNull
@Override
public String getDescription() {
diff --git a/src/main/java/com/beanbeanjuice/command/settings/raffle/SetRaffleChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/raffle/SetRaffleChannelSubCommand.java
index 5f6517f2..6c752566 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/raffle/SetRaffleChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/raffle/SetRaffleChannelSubCommand.java
@@ -4,9 +4,15 @@
import com.beanbeanjuice.utility.command.ISubCommand;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
/**
* An {@link ISubCommand} used to set the {@link com.beanbeanjuice.utility.section.moderation.raffle.Raffle Raffle} {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}.
*
@@ -16,9 +22,18 @@ public class SetRaffleChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
+ TextChannel channel = event.getTextChannel();
+ if (event.getOption("raffle_channel") != null)
+ channel = event.getOption("raffle_channel").getAsTextChannel();
+
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(channel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
// Attempt to add the raffle channel to the database.
- if (GuildHandler.getCustomGuild(event.getGuild()).setRaffleChannel(event.getChannel().getId())) {
+ if (GuildHandler.getCustomGuild(event.getGuild()).setRaffleChannel(channel.getId())) {
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Set Raffle Channel",
"This channel has been set to an active raffle channel!"
@@ -28,6 +43,15 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
event.getHook().sendMessageEmbeds(Helper.sqlServerError()).queue();
}
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.CHANNEL, "raffle_channel", "The text channel to send raffle information to.", false)
+ .setChannelTypes(ChannelType.TEXT));
+ return options;
+ }
+
@NotNull
@Override
public String getDescription() {
diff --git a/src/main/java/com/beanbeanjuice/command/settings/twitch/TwitchNotificationsChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/twitch/TwitchNotificationsChannelSubCommand.java
index 03412194..d7f698a5 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/twitch/TwitchNotificationsChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/twitch/TwitchNotificationsChannelSubCommand.java
@@ -4,6 +4,7 @@
import com.beanbeanjuice.utility.command.ISubCommand;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
@@ -24,7 +25,16 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
String command = event.getOption("option").getAsString();
if (command.equalsIgnoreCase("set")) { // Setting the twitch notifications channel
- if (GuildHandler.getCustomGuild(event.getGuild()).updateTwitchDiscordChannel(event.getChannel().getId())) {
+
+ TextChannel textChannel = event.getTextChannel();
+
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(textChannel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
+
+ if (GuildHandler.getCustomGuild(event.getGuild()).updateTwitchDiscordChannel(textChannel.getId())) {
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Set Live Channel",
"Successfully set the live channel to this channel!"
diff --git a/src/main/java/com/beanbeanjuice/command/settings/update/SetUpdateChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/update/SetUpdateChannelSubCommand.java
index 4bab0b1b..743c1e75 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/update/SetUpdateChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/update/SetUpdateChannelSubCommand.java
@@ -4,9 +4,15 @@
import com.beanbeanjuice.utility.command.ISubCommand;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
/**
* An {@link ISubCommand} used to set the current {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}
* to the update {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} in the
@@ -18,7 +24,17 @@ public class SetUpdateChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
- if (GuildHandler.getCustomGuild(event.getGuild()).setUpdateChannel(event.getChannel().getId())) {
+ TextChannel channel = event.getTextChannel();
+ if (event.getOption("update_channel") != null)
+ channel = event.getOption("update_channel").getAsTextChannel();
+
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(channel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
+
+ if (GuildHandler.getCustomGuild(event.getGuild()).setUpdateChannel(channel.getId())) {
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Set Update Channel",
"This channel will now receive bot updates! Make sure to enable notifications " +
@@ -29,10 +45,19 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
event.getHook().sendMessageEmbeds(Helper.sqlServerError()).queue();
}
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.CHANNEL, "update_channel", "The text channel to send bot update information to.", false)
+ .setChannelTypes(ChannelType.TEXT));
+ return options;
+ }
+
@NotNull
@Override
public String getDescription() {
- return "Set the current channel to the update channel!";
+ return "Set a channel to the update channel!";
}
@NotNull
diff --git a/src/main/java/com/beanbeanjuice/command/settings/venting/SetVentingChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/venting/SetVentingChannelSubCommand.java
index 8152939c..410e8cb0 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/venting/SetVentingChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/venting/SetVentingChannelSubCommand.java
@@ -4,9 +4,15 @@
import com.beanbeanjuice.utility.command.ISubCommand;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
/**
* An {@link ISubCommand} used to set the venting {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}
* for a specified {@link net.dv8tion.jda.api.entities.Guild Guild}.
@@ -17,7 +23,17 @@ public class SetVentingChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
- if (GuildHandler.getCustomGuild(event.getGuild()).setVentingChannelID(event.getChannel().getId())) {
+ TextChannel channel = event.getTextChannel();
+ if (event.getOption("venting_channel") != null)
+ channel = event.getOption("venting_channel").getAsTextChannel();
+
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(channel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
+
+ if (GuildHandler.getCustomGuild(event.getGuild()).setVentingChannelID(channel.getId())) {
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Set Venting Channel",
"This channel will now receive anonymous vents! This can cause many moderation issues within your server as " +
@@ -28,10 +44,19 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
event.getHook().sendMessageEmbeds(Helper.sqlServerError()).queue();
}
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.CHANNEL, "venting_channel", "The text channel to send anonymous vent information to.", false)
+ .setChannelTypes(ChannelType.TEXT));
+ return options;
+ }
+
@NotNull
@Override
public String getDescription() {
- return "Set the current channel to the venting channel!";
+ return "Set a channel to the venting channel!";
}
@NotNull
diff --git a/src/main/java/com/beanbeanjuice/command/settings/welcome/SetWelcomeChannelSubCommand.java b/src/main/java/com/beanbeanjuice/command/settings/welcome/SetWelcomeChannelSubCommand.java
index cc85325c..1d0dfa53 100644
--- a/src/main/java/com/beanbeanjuice/command/settings/welcome/SetWelcomeChannelSubCommand.java
+++ b/src/main/java/com/beanbeanjuice/command/settings/welcome/SetWelcomeChannelSubCommand.java
@@ -4,9 +4,15 @@
import com.beanbeanjuice.utility.command.ISubCommand;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
import com.beanbeanjuice.utility.helper.Helper;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
/**
* An {@link ISubCommand} used to set the welcome {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}
* for a specified {@link net.dv8tion.jda.api.entities.Guild Guild}.
@@ -17,7 +23,18 @@ public class SetWelcomeChannelSubCommand implements ISubCommand {
@Override
public void handle(@NotNull SlashCommandInteractionEvent event) {
- if (GuildHandler.getCustomGuild(event.getGuild()).setWelcomeChannelID(event.getChannel().getId())) {
+
+ TextChannel channel = event.getTextChannel();
+ if (event.getOption("welcome_channel") != null)
+ channel = event.getOption("welcome_channel").getAsTextChannel();
+
+ // If the channel is already set, notify them that this cannot be done.
+ if (GuildHandler.getCustomGuild(event.getGuild()).isDailyChannel(channel.getId())) {
+ event.getHook().sendMessageEmbeds(Helper.alreadyDailyChannel()).queue();
+ return;
+ }
+
+ if (GuildHandler.getCustomGuild(event.getGuild()).setWelcomeChannelID(channel.getId())) {
event.getHook().sendMessageEmbeds(Helper.successEmbed(
"Set Welcome Channel",
"This channel has been set to the welcome channel! Make sure to " +
@@ -28,10 +45,19 @@ public void handle(@NotNull SlashCommandInteractionEvent event) {
event.getHook().sendMessageEmbeds(Helper.sqlServerError()).queue();
}
+ @NotNull
+ @Override
+ public ArrayList getOptions() {
+ ArrayList options = new ArrayList<>();
+ options.add(new OptionData(OptionType.CHANNEL, "welcome_channel", "The text channel to send welcome information to.", false)
+ .setChannelTypes(ChannelType.TEXT));
+ return options;
+ }
+
@NotNull
@Override
public String getDescription() {
- return "Set the current channel to welcome channel!";
+ return "Set a channel to welcome channel!";
}
@NotNull
diff --git a/src/main/java/com/beanbeanjuice/utility/command/CommandHandler.java b/src/main/java/com/beanbeanjuice/utility/command/CommandHandler.java
index b824c871..3a64a92d 100644
--- a/src/main/java/com/beanbeanjuice/utility/command/CommandHandler.java
+++ b/src/main/java/com/beanbeanjuice/utility/command/CommandHandler.java
@@ -4,6 +4,7 @@
import com.beanbeanjuice.command.cafe.*;
import com.beanbeanjuice.command.fun.*;
import com.beanbeanjuice.command.fun.birthday.BirthdayCommand;
+import com.beanbeanjuice.command.fun.rate.RateCommand;
import com.beanbeanjuice.command.games.*;
import com.beanbeanjuice.command.generic.*;
import com.beanbeanjuice.command.moderation.AddPollCommand;
@@ -61,12 +62,15 @@ public CommandHandler(@NotNull JDA jda) {
commands.put("serve", new ServeCommand());
// Fun
+ commands.put("rate", new RateCommand());
commands.put("birthday", new BirthdayCommand());
commands.put("avatar", new AvatarCommand());
+ commands.put("banner", new BannerCommand());
commands.put("coffee-meme", new CoffeeMemeCommand());
commands.put("counting-statistics", new CountingStatisticsCommand());
commands.put("joke", new JokeCommand());
commands.put("meme", new MemeCommand());
+ commands.put("snipe", new SnipeCommand());
commands.put("tea-meme", new TeaMemeCommand());
// Games
@@ -87,8 +91,10 @@ public CommandHandler(@NotNull JDA jda) {
commands.put("feature-request", new FeatureRequestCommand());
commands.put("generate-code", new GenerateCodeCommand());
commands.put("help", new HelpCommand());
+ commands.put("info", new InfoCommand());
commands.put("ping", new PingCommand());
commands.put("remove-my-data", new RemoveMyDataCommand());
+ commands.put("stats", new StatsCommand());
commands.put("support", new SupportCommand());
commands.put("who-is", new WhoIsCommand());
diff --git a/src/main/java/com/beanbeanjuice/utility/handler/guild/CustomGuild.java b/src/main/java/com/beanbeanjuice/utility/handler/guild/CustomGuild.java
index 74cedd5b..a255af25 100644
--- a/src/main/java/com/beanbeanjuice/utility/handler/guild/CustomGuild.java
+++ b/src/main/java/com/beanbeanjuice/utility/handler/guild/CustomGuild.java
@@ -14,6 +14,7 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
+import java.util.Map;
/**
* A {@link CustomGuild} that contains {@link net.dv8tion.jda.api.entities.Guild Guild} information.
@@ -634,4 +635,28 @@ public Boolean updateTwitchDiscordChannel(String liveChannelID) {
public HashMap getCustomChannelIDs() {
return customChannelIDs;
}
+
+ /**
+ * Check is a specified {@link String channelID} is already a {@link CustomChannel}.
+ * @param channelID The {@link String channelID} to search for.
+ * @return True, if the {@link String channelID} is a {@link CustomChannel}.
+ */
+ @NotNull
+ public Boolean isCustomChannel(@NotNull String channelID) {
+ for (Map.Entry pair : customChannelIDs.entrySet()) {
+ if (pair.getValue().equalsIgnoreCase(channelID))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check if a specified {@link String channelID} is a {@link CustomChannel}.
+ * @param channelID The {@link String channelID} to search for.
+ * @return True, if the {@link String channelID} is a {@link CustomChannel}.
+ */
+ @NotNull
+ public Boolean isDailyChannel(@NotNull String channelID) {
+ return customChannelIDs.get(CustomChannel.DAILY).equalsIgnoreCase(channelID);
+ }
}
diff --git a/src/main/java/com/beanbeanjuice/utility/handler/snipe/SnipeHandler.java b/src/main/java/com/beanbeanjuice/utility/handler/snipe/SnipeHandler.java
new file mode 100644
index 00000000..8db754af
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/utility/handler/snipe/SnipeHandler.java
@@ -0,0 +1,136 @@
+package com.beanbeanjuice.utility.handler.snipe;
+
+import com.beanbeanjuice.utility.helper.Helper;
+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.events.message.MessageReceivedEvent;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A handler used for sniping {@link net.dv8tion.jda.api.entities.Message} objects.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class SnipeHandler {
+
+ private static class PreSnipeTimer extends TimerTask {
+
+ private final PreSnipeMessage preSnipeMessage;
+ private PreSnipeTimer(@NotNull PreSnipeMessage preSnipeMessage) { this.preSnipeMessage = preSnipeMessage; }
+
+ @Override
+ public void run() { removePreSnipe(preSnipeMessage); } // Remove when done.
+
+ }
+
+ private static class SnipeTimer extends TimerTask {
+
+ private final SnipeMessage snipeMessage;
+ private SnipeTimer(@NotNull SnipeMessage snipeMessage) { this.snipeMessage = snipeMessage; }
+
+ @Override
+ public void run() { removeSnipe(snipeMessage); } // Remove when done.
+
+ }
+
+ protected static class PreSnipeMessage {
+
+ protected final String channelID;
+ protected final User user;
+ protected final String messageID;
+ protected final String message;
+ protected Timer timer;
+
+ protected PreSnipeMessage(@NotNull String channelID,
+ @NotNull User user, @NotNull String messageID, @NotNull String message) {
+ this.channelID = channelID;
+ this.user = user;
+ this.messageID = messageID;
+ this.message = message;
+ timer = new Timer();
+ start();
+ }
+
+ protected void start() {
+ timer.schedule(new PreSnipeTimer(this), TimeUnit.MINUTES.toMillis(2));
+ }
+
+ }
+
+ private static class SnipeMessage extends PreSnipeMessage {
+
+ private SnipeMessage(@NotNull PreSnipeMessage snipeMessage) {
+ super(snipeMessage.channelID, snipeMessage.user, snipeMessage.messageID, snipeMessage.message);
+ }
+
+ @Override
+ protected void start() {
+ timer.schedule(new SnipeTimer(this), TimeUnit.SECONDS.toMillis(30));
+ }
+
+ @NotNull
+ private MessageEmbed getMessageEmbed() {
+ return new EmbedBuilder()
+ .setAuthor(user.getName(), null, user.getAvatarUrl())
+ .setColor(Helper.getRandomColor())
+ .setDescription(message)
+ .setFooter("Message ID: " + messageID)
+ .build();
+ }
+ }
+
+ private static final HashMap> preSnipes = new HashMap<>();
+ private static final HashMap> snipes = new HashMap<>();
+
+ public static void addPreSnipe(@NotNull MessageReceivedEvent event) {
+ // Channel IDs are unique. No need to store the guild ID.
+ String channelID = event.getChannel().getId();
+ User user = event.getAuthor();
+ String messageID = event.getMessageId();
+ String message = event.getMessage().getContentRaw();
+
+ // Adds the guild to the snipe handler, if it is not in it yet.
+ if (!preSnipes.containsKey(channelID))
+ preSnipes.put(channelID, new HashMap<>());
+
+ preSnipes.get(channelID).put(messageID, new PreSnipeMessage(channelID, user, messageID, message));
+ }
+
+ public static void moveSnipe(@NotNull String channelID, @NotNull String messageID) {
+ // Checking if the message is in presnipes.
+ if (preSnipes.containsKey(channelID) && preSnipes.get(channelID).containsKey(messageID)) {
+ PreSnipeMessage preSnipeMessage = preSnipes.get(channelID).get(messageID);
+ SnipeMessage snipeMessage = new SnipeMessage(preSnipeMessage);
+
+ if (!snipes.containsKey(channelID))
+ snipes.put(channelID, new Stack<>());
+
+ snipes.get(channelID).add(snipeMessage);
+ removePreSnipe(preSnipeMessage);
+ }
+
+ }
+
+ private static void removePreSnipe(@NotNull PreSnipeMessage preSnipeMessage) {
+ preSnipes.get(preSnipeMessage.channelID).remove(preSnipeMessage.messageID);
+ }
+
+ private static void removeSnipe(@NotNull SnipeMessage snipeMessage) {
+ snipes.get(snipeMessage.channelID).remove(snipeMessage);
+ }
+
+ @Nullable
+ public static MessageEmbed getLatestSnipe(@NotNull String channelID) {
+ if (!snipes.containsKey(channelID) || snipes.get(channelID).isEmpty())
+ return null;
+
+ return snipes.get(channelID).pop().getMessageEmbed();
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/utility/helper/Helper.java b/src/main/java/com/beanbeanjuice/utility/helper/Helper.java
index 528da00b..1fde1377 100644
--- a/src/main/java/com/beanbeanjuice/utility/helper/Helper.java
+++ b/src/main/java/com/beanbeanjuice/utility/helper/Helper.java
@@ -6,10 +6,7 @@
import com.beanbeanjuice.cafeapi.CafeAPI;
import com.beanbeanjuice.cafeapi.requests.RequestLocation;
import net.dv8tion.jda.api.EmbedBuilder;
-import net.dv8tion.jda.api.entities.Guild;
-import net.dv8tion.jda.api.entities.MessageEmbed;
-import net.dv8tion.jda.api.entities.Role;
-import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.entities.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,6 +24,9 @@
*/
public class Helper {
+ /**
+ * Start an update {@link Timer} that restarts the {@link CafeAPI}.
+ */
public static void startHourlyUpdateTimer() {
Timer updateTimer = new Timer();
TimerTask updateTimerTask = new TimerTask() {
@@ -42,6 +42,31 @@ public void run() {
updateTimer.scheduleAtFixedRate(updateTimerTask, 0, 3600000);
}
+ /**
+ * Start a timer that updates the bio every so often.
+ */
+ public static void startBioUpdateTimer() {
+ String initialString = "/help | " + Bot.BOT_VERSION + " - ";
+
+ Timer timer = new Timer();
+ TimerTask timerTask = new TimerTask() {
+ @Override
+ public void run() {
+ int num = getRandomNumber(1, 4);
+ String finalString = "";
+
+ switch (num) {
+ case 1 -> finalString = "Currently in " + getTotalServers() + " restaurants!";
+ case 2 -> finalString = "Waiting " + getTotalChannels() + " tables!";
+ case 3 -> finalString = "Serving " + getTotalUsers() + " customers!";
+ }
+
+ Bot.getBot().getPresence().setActivity(Activity.playing(initialString + finalString));
+ }
+ };
+ timer.scheduleAtFixedRate(timerTask, 0, TimeUnit.MINUTES.toMillis(1));
+ }
+
@NotNull
private static MessageEmbed getUpdateEmbed(@NotNull Long botPing, @NotNull Long gatewayPing) {
EmbedBuilder embedBuilder = new EmbedBuilder();
@@ -183,9 +208,9 @@ public static MessageEmbed sqlServerError(@Nullable String optionalMessage) {
String description = "The bot is unable to connect to the SQL database. Please try again later.";
- if (optionalMessage != null) {
+ if (optionalMessage != null)
description += " - " + optionalMessage;
- }
+
embedBuilder.setDescription(description);
return embedBuilder.build();
}
@@ -198,26 +223,44 @@ public static MessageEmbed sqlServerError(@Nullable String optionalMessage) {
*/
@NotNull
public static MessageEmbed errorEmbed(@NotNull String title, @NotNull String description) {
- EmbedBuilder embedBuilder = new EmbedBuilder();
- embedBuilder.setTitle(title);
- embedBuilder.setDescription(description);
- embedBuilder.setColor(Color.red);
- return embedBuilder.build();
+ return new EmbedBuilder()
+ .setTitle(title)
+ .setDescription(description)
+ .setColor(Color.red)
+ .build();
}
/**
* Creates a success {@link MessageEmbed}.
* @param title The title for the {@link MessageEmbed}.
* @param description The description for the {@link MessageEmbed}.
- * @return The creates {@link MessageEmbed}.
+ * @return The created {@link MessageEmbed}.
*/
@NotNull
public static MessageEmbed successEmbed(@NotNull String title, @NotNull String description) {
- EmbedBuilder embedBuilder = new EmbedBuilder();
- embedBuilder.setTitle(title);
- embedBuilder.setDescription(description);
- embedBuilder.setColor(getRandomColor());
- return embedBuilder.build();
+ return new EmbedBuilder()
+ .setTitle(title)
+ .setDescription(description)
+ .setColor(getRandomColor())
+ .build();
+ }
+
+ /**
+ * Creates a small {@link MessageEmbed}.
+ * @param author The {@link String author} or {@link String title} for the {@link MessageEmbed}.
+ * @param url The {@link String url} for the {@link MessageEmbed}.
+ * @param authorImageURL The {@link String url} for the icon to show up next to the author.
+ * @param description The {@link String description} of the {@link MessageEmbed}.
+ * @return The created {@link MessageEmbed}.
+ */
+ @NotNull
+ public static MessageEmbed smallAuthorEmbed(@NotNull String author, @Nullable String url, @NotNull String authorImageURL,
+ @NotNull String description) {
+ return new EmbedBuilder()
+ .setAuthor(author, url, authorImageURL)
+ .setDescription(description)
+ .setColor(getRandomColor())
+ .build();
}
/**
@@ -251,8 +294,8 @@ public static Double roundDouble(@NotNull Double amount) {
/**
* Get a random number.
- * @param minimum The minimum {@link Integer}.
- * @param maximum The maximum {@link Integer}.
+ * @param minimum The minimum {@link Integer}. Inclusive.
+ * @param maximum The maximum {@link Integer}. Exclusive.
* @return The random {@link Integer}.
*/
@NotNull
@@ -328,4 +371,41 @@ public static String getRandomAlphaNumericString(@NotNull Integer n) {
return sb.toString();
}
+ /**
+ * @return A {@link MessageEmbed} specifying that the selected channel is already a Daily channel.
+ */
+ @NotNull
+ public static MessageEmbed alreadyDailyChannel() {
+ return Helper.errorEmbed(
+ "Specified Channel is Daily Channel",
+ "The channel you have specified is already set to the daily channel. " +
+ "This means that it cannot be set to this channel. You can choose another channel " +
+ "or remove the specified channel from being a daily-reset channel."
+ );
+ }
+
+ /**
+ * @return Get the {@link Integer total} channels the bot is responsible for.
+ */
+ @NotNull
+ public static Integer getTotalChannels() {
+ return Bot.getBot().getTextChannels().size();
+ }
+
+ /**
+ * @return Get the {@link Integer total} servers the bot is responsible for.
+ */
+ @NotNull
+ public static Integer getTotalServers() {
+ return Bot.getBot().getGuilds().size();
+ }
+
+ /**
+ * @return Get the {@link Integer total} users the bot is responsible for.
+ */
+ @NotNull
+ public static Integer getTotalUsers() {
+ return Bot.getBot().getUsers().size();
+ }
+
}
diff --git a/src/main/java/com/beanbeanjuice/utility/listener/AIResponseListener.java b/src/main/java/com/beanbeanjuice/utility/listener/AIResponseListener.java
index 545e908b..22b74cdc 100644
--- a/src/main/java/com/beanbeanjuice/utility/listener/AIResponseListener.java
+++ b/src/main/java/com/beanbeanjuice/utility/listener/AIResponseListener.java
@@ -16,11 +16,15 @@
* appropriate response depending on if it is enabled in the {@link Guild}.
*
* @author beanbeanjuice
+ * @since v3.0.0
*/
public class AIResponseListener extends ListenerAdapter {
private final HashMap, ArrayList> messageMap;
+ /**
+ * Create a new {@link AIResponseListener} object.
+ */
public AIResponseListener() {
messageMap = new HashMap<>();
@@ -40,6 +44,7 @@ private void createMaps() {
createSTFUMaps();
createGenevieveMaps();
createMikoriMaps();
+ createHPMaps();
createMeowMaps();
createWoofMaps();
}
@@ -51,6 +56,7 @@ private void createHelloMaps() {
commandTerms.add("hello");
commandTerms.add("hi");
commandTerms.add("hey");
+ commandTerms.add("hai");
responses.add("Hi, {user}!");
responses.add("Hey hey, {user}! ^-^");
@@ -247,6 +253,23 @@ private void createMikoriMaps() {
responses.add("Mikori? Mikori... hmmm.. I've heard their name before but not good things.");
responses.add("My creator tells me to stay away from someone named Mikori...");
responses.add("Mikori? <:madison_when_short:843673314990882836> STAY AWAY");
+ responses.add("Mikori seems like a TERRIBLE person...");
+
+ messageMap.put(commandTerms, responses);
+ }
+
+ private void createHPMaps() {
+ ArrayList commandTerms = new ArrayList<>();
+ ArrayList responses = new ArrayList<>();
+
+ commandTerms.add("hp");
+ commandTerms.add("horsepower");
+ commandTerms.add("horse power");
+
+ responses.add("HP? Horsepower? I heard they're friends with Miko... so I'm not sure how smart they are.");
+ responses.add("I heard HP is delusional.");
+ responses.add("Hmm... who's HP? Because I heard they're not kind at all.");
+ responses.add("I heard her and Miko attacked someone...");
messageMap.put(commandTerms, responses);
}
diff --git a/src/main/java/com/beanbeanjuice/utility/listener/MessageDeleteListener.java b/src/main/java/com/beanbeanjuice/utility/listener/MessageDeleteListener.java
new file mode 100644
index 00000000..0b6aa9bd
--- /dev/null
+++ b/src/main/java/com/beanbeanjuice/utility/listener/MessageDeleteListener.java
@@ -0,0 +1,23 @@
+package com.beanbeanjuice.utility.listener;
+
+import com.beanbeanjuice.utility.handler.snipe.SnipeHandler;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.events.message.MessageDeleteEvent;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * A {@link ListenerAdapter} that listens for {@link net.dv8tion.jda.api.events.message.MessageDeleteEvent MessageDeleteEvent}.
+ *
+ * @author beanbeanjuice
+ * @since v3.1.0
+ */
+public class MessageDeleteListener extends ListenerAdapter {
+
+ @Override
+ public void onMessageDelete(@NotNull MessageDeleteEvent event) {
+ if (event.isFromGuild() && event.getChannelType() == ChannelType.TEXT)
+ SnipeHandler.moveSnipe(event.getTextChannel().getId(), event.getMessageId());
+ }
+
+}
diff --git a/src/main/java/com/beanbeanjuice/utility/listener/MessageListener.java b/src/main/java/com/beanbeanjuice/utility/listener/MessageListener.java
index 5647c00c..ec82aa68 100644
--- a/src/main/java/com/beanbeanjuice/utility/listener/MessageListener.java
+++ b/src/main/java/com/beanbeanjuice/utility/listener/MessageListener.java
@@ -2,9 +2,11 @@
import com.beanbeanjuice.utility.handler.CountingHandler;
import com.beanbeanjuice.utility.handler.guild.GuildHandler;
+import com.beanbeanjuice.utility.handler.snipe.SnipeHandler;
import com.beanbeanjuice.utility.helper.Helper;
import com.beanbeanjuice.utility.handler.guild.CustomGuild;
import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
@@ -25,6 +27,9 @@ public void onMessageReceived(@NotNull MessageReceivedEvent event) {
if (!event.isFromGuild()) { return; }
+ if (event.getChannelType() == ChannelType.TEXT)
+ SnipeHandler.addPreSnipe(event);
+
CustomGuild guildInformation = GuildHandler.getCustomGuild(event.getGuild());
// Checking if the event is a counting channel
diff --git a/src/main/java/com/beanbeanjuice/utility/listener/ServerListener.java b/src/main/java/com/beanbeanjuice/utility/listener/ServerListener.java
index b1c4b856..7f68048e 100644
--- a/src/main/java/com/beanbeanjuice/utility/listener/ServerListener.java
+++ b/src/main/java/com/beanbeanjuice/utility/listener/ServerListener.java
@@ -33,7 +33,6 @@ public void onGuildJoin(@NotNull GuildJoinEvent event) {
}
GuildHandler.addGuild(event.getGuild());
- Bot.updateGuildPresence(); // Updates the amount of servers in the status.
Bot.getLogger().log(this.getClass(), LogLevel.INFO, "`" + event.getGuild().getName() + "` has added me! :blush:", false, true);
}
@@ -41,9 +40,7 @@ public void onGuildJoin(@NotNull GuildJoinEvent event) {
public void onGuildLeave(@NotNull GuildLeaveEvent event) {
super.onGuildLeave(event);
GuildHandler.removeGuild(event.getGuild());
- Bot.updateGuildPresence(); // Updates the amount of servers in the status.
Bot.getLogger().log(ServerListener.class, LogLevel.INFO, "`" + event.getGuild().getName() + "` has removed me... :pleading_face:", false, true);
-
}
@NotNull
diff --git a/src/main/java/com/beanbeanjuice/utility/logging/LogManager.java b/src/main/java/com/beanbeanjuice/utility/logging/LogManager.java
index accaf348..23d3d945 100644
--- a/src/main/java/com/beanbeanjuice/utility/logging/LogManager.java
+++ b/src/main/java/com/beanbeanjuice/utility/logging/LogManager.java
@@ -64,19 +64,22 @@ private void checkFiles() {
// Setting the current log file time.
logFileTime = time.format("MM-dd-yyyy");
+ boolean newDirectoryCreated = false;
File file = new File(filePath);
if (!file.exists())
- file.mkdir();
+ newDirectoryCreated = file.mkdir();
compressOldLogs();
// If the log file already exists, it doesn't need to make a new one.
- if (!createLogFile(filePath)) {
- log(this.getClass(), LogLevel.INFO, "Log for today has already been created.");
- } else {
- log(this.getClass(), LogLevel.OKAY, "Created Log File!");
- }
+ if (!createLogFile(filePath))
+ log(LogManager.class, LogLevel.INFO, "Log for today has already been created.");
+ else
+ log(LogManager.class, LogLevel.OKAY, "Created Log File!");
+
+ if (!newDirectoryCreated)
+ log(LogManager.class, LogLevel.WARN, "No new directory has been created...");
}
private void logStackTrace(@NotNull Throwable exception) {
@@ -317,10 +320,8 @@ public void log(@NotNull Class> c, @NotNull LogLevel logLevel, @NotNull String
public void log(@NotNull Class> c, @NotNull LogLevel logLevel, @NotNull String message,
@NotNull Boolean logToWebhook, @NotNull Boolean logToLogChannel, @Nullable Throwable exception) {
- if (!time.format("MM-dd-yyyy").equals(logFileTime)) {
- log(this.getClass(), LogLevel.INFO, "New day... creating new log file.", true, true);
+ if (!time.format("MM-dd-yyyy").equals(logFileTime))
checkFiles();
- }
Logger logger = LoggerFactory.getLogger(c);
diff --git a/src/main/java/com/beanbeanjuice/utility/section/cafe/MenuHandler.java b/src/main/java/com/beanbeanjuice/utility/section/cafe/MenuHandler.java
index 699693b2..89a55f68 100644
--- a/src/main/java/com/beanbeanjuice/utility/section/cafe/MenuHandler.java
+++ b/src/main/java/com/beanbeanjuice/utility/section/cafe/MenuHandler.java
@@ -35,6 +35,7 @@ private static void createMenuItems() {
breakfasts.add(new MenuItem(CafeCategory.BREAKFAST, "Everything Omelette", 8.25, "An everything omelette! This has eggs, bacon, cheese, and so much more!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/breakfasts/omelette.jpg"));
breakfasts.add(new MenuItem(CafeCategory.BREAKFAST, "French Toast", 4.75, "Some french toast with maple syrup!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/breakfasts/french_toast.webp"));
breakfasts.add(new MenuItem(CafeCategory.BREAKFAST, "Breakfast Sandwich", 5.5, "Bacon, egg, and cheese sandwich!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/breakfasts/bacon_egg_and_cheese_sandwich.jpg"));
+ breakfasts.add(new MenuItem(CafeCategory.BREAKFAST, "Egg Fried Rice", 15.0, "Some rice fried with eggs and green onion.", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/breakfasts/egg_fried_rice.png"));
menu.put(CafeCategory.BREAKFAST, breakfasts);
// Drinks
@@ -70,6 +71,7 @@ private static void createMenuItems() {
soups.add(new MenuItem(CafeCategory.SOUP, "Mushroom Soup", 3.25, "I've personally never had this...", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/soups/mushroom_soup.jpg"));
soups.add(new MenuItem(CafeCategory.SOUP, "Lobster Bisque", 3.25, "Yummy yummy in my tummy!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/soups/lobster_bisque.jpg"));
soups.add(new MenuItem(CafeCategory.SOUP, "Clam Chowder", 3.25, "This is... honestly really good.", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/soups/clam_chowder_soup.jpg"));
+ soups.add(new MenuItem(CafeCategory.SOUP, "Comforting Ramen", 15.0, "Some delicious, calming, ramen to take your troubles away!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/soups/ramen.png"));
menu.put(CafeCategory.SOUP, soups);
// Sides and Condiments
@@ -84,6 +86,8 @@ private static void createMenuItems() {
sides.add(new MenuItem(CafeCategory.SIDE, "Popcorn Chicken", 1.5, "MMmmmm these are my favourite...", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sides/popcorn_chicken.jpg"));
sides.add(new MenuItem(CafeCategory.SIDE, "Egg Puffs", 1.5, "Some cheese egg puffs! These might go well with some coffee! *wink*", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sides/egg_puffs.jpg"));
sides.add(new MenuItem(CafeCategory.SIDE, "Chicken Nuggets", 1.5, "Chicken nuggets with sweet and sour sauce. As it should be!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sides/chicken_nuggets.jpg"));
+ sides.add(new MenuItem(CafeCategory.SIDE, "Silly Sushi", 5.0, "Some small and silly-looking sushi with homemade rice and seaweed!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sides/sushi.png"));
+ sides.add(new MenuItem(CafeCategory.SIDE, "Festival Potatoes", 19.0, "Some festive potatoes... for festivals!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sides/festival_potatoes.png"));
menu.put(CafeCategory.SIDE, sides);
// Fruits
@@ -108,6 +112,10 @@ private static void createMenuItems() {
sweets.add(new MenuItem(CafeCategory.SWEET, "Vanilla Ice Cream", 0.75, "A scoop of vanilla ice cream. I'm sorry... we ran out of other flavours...", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sweets/vanilla_ice_cream.gif"));
sweets.add(new MenuItem(CafeCategory.SWEET, "Ice Cream Waffles", 3.5, "A nice warm waffle with some nice cold vanilla ice cream!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sweets/ice_cream_waffles.jpg"));
sweets.add(new MenuItem(CafeCategory.SWEET, "Cheese Cake", 2.5, "A nice warm slice of cheese cake!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sweets/cheese_cake.jpg"));
+ sweets.add(new MenuItem(CafeCategory.SWEET, "Refreshing Strawberry Cake", 10.0, "A refreshing strawberry cake! Recipe by yours truly~", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sweets/strawberry_cake.png"));
+ sweets.add(new MenuItem(CafeCategory.SWEET, "Peach Yogurt", 12.0, "Very refreshing and cold for the summer months~ ๐", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sweets/peach_yogurt.png"));
+ sweets.add(new MenuItem(CafeCategory.SWEET, "Cute Biscuits", 25.0, "Amazing for parties with friends UwU", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sweets/biscuits.png"));
+ sweets.add(new MenuItem(CafeCategory.SWEET, "Assorted Cupcakes", 10.0, "Some assorted cupcakes to bring home with you after a hard day's work!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/sweets/assorted_cupcakes.png"));
menu.put(CafeCategory.SWEET, sweets);
// Alcohol
@@ -122,12 +130,13 @@ private static void createMenuItems() {
// Secret
ArrayList secrets = new ArrayList<>();
secrets.add(new MenuItem(CafeCategory.SECRET, "The \"One Tap\"", 10.0, "A 69oz cup of Swedish fish GFUEL.", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/the_one_tap.webp"));
- secrets.add(new MenuItem(CafeCategory.SECRET, "Otter Pop", 4.0, "A nice cold otter pop to get you through a hot day. They're Lilly's favourite!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/otter_pop.jpg"));
- secrets.add(new MenuItem(CafeCategory.SECRET, "The Duo", 20.0, "A giant bucket of popcorn and extra cheddar goldfish mixed together. Enough for two! A signature dish by Lilly and Will. โค", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/the_duo.webp"));
- secrets.add(new MenuItem(CafeCategory.SECRET, "The Kenzie Special", 7.0, "An entire bottle of *not* vodka and some apple juice...", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/the_kenzie_special.jpg"));
+ secrets.add(new MenuItem(CafeCategory.SECRET, "The Kenzie Special", 150.0, "An entire bottle of *not* vodka and some apple juice...", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/the_kenzie_special.jpg"));
secrets.add(new MenuItem(CafeCategory.SECRET, "Chicken Coop", 12.5, "Some fluffy nuggets, a choco puff drink for your thirst, and some sunflower seeds!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/chicken_coop.gif"));
- secrets.add(new MenuItem(CafeCategory.SECRET, "Sprout Moment", 3.0, "A yummy, cold aloe drink! Just a little refreshing signature drink from Sprout!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/sprout_moment.jpg"));
- secrets.add(new MenuItem(CafeCategory.SECRET, "Boba GFUEL", 3.0, "A nice yum yum bubble tea in the GFUEL flavour of your choice!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/boba_gfuel.jpg"));
+ secrets.add(new MenuItem(CafeCategory.SECRET, "Sprout Moment", 45.0, "A yummy, cold aloe drink! Just a little refreshing signature drink from Sprout!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/sprout_moment.jpg"));
+ secrets.add(new MenuItem(CafeCategory.SECRET, "Boba GFUEL", 69.0, "A nice yum yum bubble tea in the GFUEL flavour of your choice!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/boba_gfuel.jpg"));
+ secrets.add(new MenuItem(CafeCategory.SECRET, "Milkie's Milky Root-Beer Float", 99.0, "Milkie's signature root-beer float aerated with milk!~", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/milkie_root_beer_float.png"));
+ secrets.add(new MenuItem(CafeCategory.SECRET, "Genevieve's Simple Bento Box", 50.0, "A simple bento box envisioned by a charming and beautiful girl!", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/genevieve_bento_box.png"));
+ secrets.add(new MenuItem(CafeCategory.SECRET, "Among Us Chicken Nuggets", 150.0, "๐", "https://cdn.beanbeanjuice.com/images/cafeBot/cafe_menu/secrets/among_us_chicken_nuggets.png"));
menu.put(CafeCategory.SECRET, secrets);
}
diff --git a/src/main/java/com/beanbeanjuice/utility/section/twitch/TwitchMessageEventHandler.java b/src/main/java/com/beanbeanjuice/utility/section/twitch/TwitchMessageEventHandler.java
index 5a60e2bb..53771360 100644
--- a/src/main/java/com/beanbeanjuice/utility/section/twitch/TwitchMessageEventHandler.java
+++ b/src/main/java/com/beanbeanjuice/utility/section/twitch/TwitchMessageEventHandler.java
@@ -82,7 +82,7 @@ public MessageEmbed liveEmbed(@NotNull ChannelGoLiveEvent event) {
.setThumbnail(userProfileImage)
.addField("Game", event.getStream().getGameName(), true)
.addField("Viewers", String.valueOf(event.getStream().getViewerCount()), true)
- .setFooter("Live information brought to you buy cafeBot!")
+ .setFooter("Live information brought to you by cafeBot!")
.build();
}