diff --git a/.gitignore b/.gitignore
index acb08a7..e02c370 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+.idea
+
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
diff --git a/pom.xml b/pom.xml
index 28e7ebd..bb33a12 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,21 +22,28 @@
JDA
LATEST
-
- mysql
- mysql-connector-java
- 5.1.38
- compile
-
com.fasterxml.jackson.dataformat
jackson-dataformat-yaml
- 2.3.0
+ LATEST
com.fasterxml.jackson.core
jackson-databind
- 2.2.3
+ LATEST
+ compile
+
+
+ com.sedmelluq
+ lavaplayer
+ LATEST
+ compile
+
+
+ mysql
+ mysql-connector-java
+ 5.1.38
+ compile
org.apache.commons
@@ -54,7 +61,6 @@
4.3.9.RELEASE
compile
-
ca.pjer
chatter-bot-api
@@ -96,7 +102,6 @@
-
false
@@ -112,17 +117,6 @@
-
- maven-surefire-plugin
- 2.19.1
-
- false
- false
-
- **/*.java
-
-
-
\ No newline at end of file
diff --git a/src/main/java/io/rixa/bot/Rixa.java b/src/main/java/io/rixa/bot/Rixa.java
index 0b6dd53..946d4e1 100644
--- a/src/main/java/io/rixa/bot/Rixa.java
+++ b/src/main/java/io/rixa/bot/Rixa.java
@@ -2,17 +2,22 @@ package io.rixa.bot;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
-import io.rixa.bot.commands.cmds.general.InfoCommand;
-import io.rixa.bot.commands.cmds.general.PingCommand;
-import io.rixa.bot.commands.cmds.general.ServerInfoCommand;
+import io.rixa.bot.commands.cmds.admin.PMCommand;
+import io.rixa.bot.commands.cmds.general.*;
+import io.rixa.bot.commands.cmds.moderator.ClearCommand;
+import io.rixa.bot.commands.cmds.moderator.MuteCommand;
+import io.rixa.bot.commands.cmds.other.ShutdownCommand;
import io.rixa.bot.commands.handler.CommandHandler;
import io.rixa.bot.commands.perms.RixaPermission;
-import io.rixa.bot.commands.cmds.general.HelpCommand;
import io.rixa.bot.data.config.Configuration;
import io.rixa.bot.data.storage.DatabaseAdapter;
import io.rixa.bot.events.BotJoinListener;
import io.rixa.bot.events.MessageListener;
import io.rixa.bot.events.ReadyListener;
+import io.rixa.bot.events.UserListener;
+import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.manager.GuildManager;
+import io.rixa.bot.guild.modules.module.MusicModule;
import io.rixa.bot.utils.FileUtils;
import lombok.Getter;
import net.dv8tion.jda.core.AccountType;
@@ -28,25 +33,33 @@ import javax.security.auth.login.LoginException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
public class Rixa {
private static Rixa instance;
- @Getter private CommandHandler commandHandler;
- @Getter private Configuration configuration;
- @Getter private ObjectMapper objectMapper;
- @Getter private List shardList;
- @Getter private File defaultPath;
- @Getter private Logger logger;
+ @Getter
+ private CommandHandler commandHandler;
+ @Getter
+ private Configuration configuration;
+ @Getter
+ private ObjectMapper objectMapper;
+ @Getter
+ private List shardList;
+ @Getter
+ private File defaultPath;
+ @Getter
+ private Logger logger;
private static long timeUp;
private Rixa() {
instance = this;
logger = Logger.getLogger(Rixa.class.getCanonicalName());
objectMapper = new ObjectMapper(new YAMLFactory());
- defaultPath = new File("Rixa");
+ defaultPath = new File("Rixa/");
commandHandler = new CommandHandler();
shardList = new ArrayList<>();
defaultPath.mkdirs();
@@ -55,41 +68,68 @@ public class Rixa {
loadJDA();
}
- public static long getTimeUp() {
+ public long getTimeUp() {
return timeUp;
}
private void loadJDA() {
+ System.out.println("SHARDS: " + configuration.getShards()); // Remove this
JDABuilder jda = new JDABuilder(AccountType.BOT)
.setToken(configuration.getToken())
.setGame(Game.of(configuration.getBotGame()))
.setEventManager(new AnnotatedEventManager())
- .addEventListener(new ReadyListener(), new BotJoinListener(), new MessageListener())
+ .addEventListener(new ReadyListener(), new BotJoinListener(), new MessageListener(),
+ new UserListener())
.setAutoReconnect(true)
.setAudioEnabled(true)
.setEnableShutdownHook(false)
.setStatus(OnlineStatus.ONLINE);
for (int i = 0; i < configuration.getShards(); i++) {
try {
- getLogger().info("Loading Shard #" + (i + 1) + "!");
- getShardList().add(jda.useSharding(i, configuration.getShards()).buildBlocking());
- getLogger().info("Shard #" + (i + 1) + " has been loaded");
+ getLogger().info("Loading Shard #" + (i + 1) + "!");
+ getShardList().add(jda.useSharding(i, configuration.getShards()).buildBlocking());
+ getLogger().info("Shard #" + (i + 1) + " has been loaded");
Thread.sleep(5000);
} catch (InterruptedException | RateLimitedException | LoginException e) {
e.printStackTrace();
}
}
- Runtime.getRuntime().addShutdownHook(new Thread(() -> getShardList().forEach(JDA::shutdown)));
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ getShardList().forEach(JDA::shutdown);
+ getShardList().forEach(jdaInstance -> {
+ jdaInstance.getGuilds().forEach((Guild guild) -> {
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild);
+ MusicModule musicModule = (MusicModule) rixaGuild.getModule("Music");
+ musicModule.getMusicManager().getScheduler().getQueue().clear();
+ musicModule.getMusicManager().getScheduler().getPlayer().destroy();
+ guild.getAudioManager().setSendingHandler(null);
+ rixaGuild.save();
+ });
+ jdaInstance.shutdown();
+ });
+ }));
timeUp = System.currentTimeMillis();
}
private void registerCommands() {
this.commandHandler.registerCommands(
+ new AdviceCommand("advice", RixaPermission.NONE, "Receive advice from the great beyond..."),
+ new ClearCommand("clear", RixaPermission.NONE, "Clear Chat!", Arrays.asList("deletemessages", "cmessages")),
+ new FeaturesCommand("features", RixaPermission.NONE, "List Rixa's official features!"),
new HelpCommand("help", RixaPermission.NONE, "Review commands and its usages!"),
new InfoCommand("info", RixaPermission.NONE, "Review information about a user or Rixa!"),
+ new MinecraftCommand("minecraft", RixaPermission.NONE, "See minecraft server info", Collections.singletonList("mc")),
+ new ModulesCommand("modules", RixaPermission.NONE, "List both enabled & disabled features of Rixa for this server!"),
+ new MusicCommand("music", RixaPermission.NONE, "Listen to music right from discord!"),
+ new MuteCommand("mute", RixaPermission.NONE, "Mute those pesky children!"),
+ new PingCommand("ping", RixaPermission.NONE, "Check Rixa's ping!"),
+ new PMCommand("pm", RixaPermission.NONE, "Private Message all users with a specific role!"),
+ new QuoteCommand("quote", RixaPermission.NONE, "Receive a quote from some of the greatest authors!"),
+ new RoleMemberList("listmembers", RixaPermission.NONE, "List all users with a specific role!"),
new ServerInfoCommand("serverinfo", RixaPermission.NONE, "Review information about the server!"),
- new PingCommand("ping", RixaPermission.NONE, "Check Rixa's ping!")
- );
+ new ShutdownCommand("shutdown", RixaPermission.NONE, "Shutdown Rixa!"),
+ new UrbanDictionaryCommand("ud", RixaPermission.NONE, "Look up urban definitions!"),
+ new YoutubeCommand("youtube", RixaPermission.NONE, "Search for music on youtube!"));
}
private void loadConfiguration() {
@@ -113,7 +153,7 @@ public class Rixa {
for (JDA jda : Rixa.getInstance().getShardList()) {
System.out.println(jda.getShardInfo().toString());
System.out.println("JDA GUILDS:" + jda.getGuilds().size());
- if (jda == null || jda.getGuilds().size() == 0 || jda.getGuildById(id) == null) continue;
+ if (jda.getGuilds().size() == 0 || jda.getGuildById(id) == null) continue;
guild = jda.getGuildById(id);
break;
}
diff --git a/src/main/java/io/rixa/bot/apis/UrbanDictionary.java b/src/main/java/io/rixa/bot/apis/UrbanDictionary.java
new file mode 100644
index 0000000..2249fc9
--- /dev/null
+++ b/src/main/java/io/rixa/bot/apis/UrbanDictionary.java
@@ -0,0 +1,48 @@
+package io.rixa.bot.apis;
+
+import lombok.Getter;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Scanner;
+
+public class UrbanDictionary {
+
+ @Getter
+ private String wordToSearch;
+ @Getter
+ private String definition;
+ @Getter
+ private String permaLink;
+ public UrbanDictionary(String wordToSearch) {
+ this.wordToSearch = wordToSearch;
+ }
+
+ public boolean search() throws IOException {
+ URL url = new URL("http://api.urbandictionary.com/v0/define?term=" + wordToSearch);
+ InputStream in = url.openStream();
+ Scanner scan = new Scanner(in);
+ String jsonString = "";
+ while(scan.hasNext()){
+ jsonString += scan.next() + " ";
+ }
+ scan.close();
+ in.close();
+ try {
+ JSONObject obj = new JSONObject(jsonString.trim());
+ JSONArray array = obj.getJSONArray("list");
+ JSONObject newObj = array.getJSONObject(0);
+ this.wordToSearch = newObj.getString("word");
+ this.permaLink = newObj.getString("permalink");
+ this.definition = newObj.getString("definition");
+ return true;
+ } catch(JSONException ex) {
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/io/rixa/bot/apis/YoutubeSearch.java b/src/main/java/io/rixa/bot/apis/YoutubeSearch.java
new file mode 100644
index 0000000..bb0bb75
--- /dev/null
+++ b/src/main/java/io/rixa/bot/apis/YoutubeSearch.java
@@ -0,0 +1,103 @@
+package io.rixa.bot.apis;
+
+import io.rixa.bot.utils.WebUtil;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+public class YoutubeSearch {
+
+ private static final String API_KEY;
+ private JSONArray items;
+
+ static {
+ API_KEY = "AIzaSyD1wjRGbzKgvjqAU25pREy1dVio9WpcuS0";
+ }
+
+ public YoutubeSearch(String query) throws IOException {
+ try {
+ String url = "https://www.googleapis.com/youtube/v3/search?"
+ + "q=" + URLEncoder.encode(query, "UTF-8")
+ + "&part=id%2Csnippet&safeSearch=none&key=" + API_KEY;
+ search(url);
+ } catch (UnsupportedEncodingException ignored) {
+ }
+ }
+
+
+ public String getKind(int index) {
+ return items.getJSONObject(index).getString("kind");
+ }
+
+ public String getIdKind(int index) {
+ return items.getJSONObject(index).getJSONObject("id").getString("kind");
+ }
+
+ public String getVideoId(int index) {
+ if (!hasVideoId(index)) {
+ index++;
+ }
+ return items.getJSONObject(index).getJSONObject("id").getString("videoId");
+ }
+
+ public boolean hasVideoId(int index) {
+ return items.getJSONObject(index).getJSONObject("id").has("videoID");
+ }
+
+ public String getPublishedTime(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getString("publishedAt");
+ }
+
+ public String getChannelId(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getString("channelId");
+ }
+
+ public String getTitle(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getString("title");
+ }
+
+ public String getDescription(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getString("description");
+ }
+
+ public String getChannelTitle(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getString("channelTitle");
+ }
+
+ public String getLiveBroadcastContent(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getString("liveBroadcastContent");
+ }
+
+ public String getThumbnailDefaultUrl(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getJSONObject("default").getString("url");
+ }
+
+ public String getThumbnailMediumUrl(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getJSONObject("medium").getString("url");
+ }
+
+ public String getThumbnailHighUrl(int index) {
+ return items.getJSONObject(index).getJSONObject("snippet").getJSONObject("high").getString("url");
+ }
+
+ public String getUrl(int index) {
+ String YOUTUBE_WATCH_BASE_URL = "https://www.youtube.com/watch?v=";
+ return YOUTUBE_WATCH_BASE_URL + getVideoId(index);
+ }
+
+ private void search(String url) throws IOException {
+ String json = WebUtil.getWebPage(url);
+
+ JSONObject obj = new JSONObject(json);
+ try {
+ items = obj.getJSONArray("items");
+ } catch (JSONException e) {
+ System.out.println("No search results found.");// throw new NotFoundException("No results found.");
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/io/rixa/bot/commands/Command.java b/src/main/java/io/rixa/bot/commands/Command.java
index 3077b70..9b67a85 100644
--- a/src/main/java/io/rixa/bot/commands/Command.java
+++ b/src/main/java/io/rixa/bot/commands/Command.java
@@ -3,8 +3,12 @@ package io.rixa.bot.commands;
import io.rixa.bot.commands.perms.RixaPermission;
import lombok.Getter;
import lombok.Setter;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
+import java.io.IOException;
import java.util.Collections;
import java.util.List;
@@ -32,5 +36,7 @@ public abstract class Command {
setAliases(aliases);
}
- public abstract void execute(GuildMessageReceivedEvent event);
+ // public abstract void execute(GuildMessageReceivedEvent event);
+
+ public abstract void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) throws IOException;
}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/admin/PMCommand.java b/src/main/java/io/rixa/bot/commands/cmds/admin/PMCommand.java
new file mode 100644
index 0000000..aa074a7
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/admin/PMCommand.java
@@ -0,0 +1,48 @@
+package io.rixa.bot.commands.cmds.admin;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.utils.DiscordUtils;
+import io.rixa.bot.utils.MessageFactory;
+import lombok.Getter;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.Role;
+import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.exceptions.ErrorResponseException;
+import net.dv8tion.jda.core.requests.ErrorResponse;
+
+public class PMCommand extends Command {
+
+ @Getter private RixaPermission rixaPermission;
+ public PMCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ this.rixaPermission = rixaPermission;
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ String msg = String.join(" ", args);
+ Role role = DiscordUtils.getMentionedRole(guild, msg);
+ if (role == null) {
+ MessageFactory.create(String.format
+ ("You must mention a role to private message! Example: `%s @role this is a test private message!`",
+ commandLabel)).queue(channel);
+ return;
+ }
+ msg = msg.replaceFirst(role.getAsMention(), "").replaceFirst("@" + role.getName(),"");
+ int usersWithRole = 0;
+ int sendingFailed = 0;
+ for (Member memberWithRole : guild.getMembersWithRoles(role)) {
+ try {
+ memberWithRole.getUser().openPrivateChannel().complete().sendMessage(msg).queue();
+ usersWithRole++;
+ } catch (ErrorResponseException ex) {
+ if (ex.getErrorResponse() == ErrorResponse.CANNOT_SEND_TO_USER)
+ sendingFailed++;
+ }
+ }
+ MessageFactory.create("```" + msg + "```")
+ .footer("Successful Deliveries: " + usersWithRole + " | Failed Deliveries: " + sendingFailed, guild.getIconUrl()).queue(channel);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/AdviceCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/AdviceCommand.java
new file mode 100644
index 0000000..a45a8f8
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/AdviceCommand.java
@@ -0,0 +1,39 @@
+package io.rixa.bot.commands.cmds.general;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.utils.MessageFactory;
+import io.rixa.bot.utils.WebUtil;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
+import org.json.JSONObject;
+
+import java.io.IOException;
+
+public class AdviceCommand extends Command {
+
+ public AdviceCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ MessageFactory.create(getAdvice()).setTitle("Advice Request").footer("Requested by: " + member.getEffectiveName(), member.getUser().getEffectiveAvatarUrl())
+ .setColor(member.getColor()).queue(channel);
+ }
+
+ private String getAdvice() {
+ String json;
+ try {
+ json = WebUtil.getWebPage("http://api.adviceslip.com/advice");
+ } catch (IOException e) {
+ return "Could not find any advice for you.";
+ }
+
+ JSONObject obj = new JSONObject(json);
+ JSONObject slip = obj.getJSONObject("slip");
+ return slip.getString("advice");
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/FeaturesCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/FeaturesCommand.java
new file mode 100644
index 0000000..4296ddb
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/FeaturesCommand.java
@@ -0,0 +1,30 @@
+package io.rixa.bot.commands.cmds.general;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.manager.GuildManager;
+import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+
+public class FeaturesCommand extends Command {
+
+ private String[] features = {
+ "Music", "Economy", "Moderation", "Server List", "User Profiles",
+ "Role Management", "Fun Commands", "Custom Commands", "Games", "& more."
+ };
+
+ public FeaturesCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild);
+ MessageFactory.create((features == null || features.length == 0) ? "There are currently no features listed." :
+ "Rixa Features: " + String.join("\n", features
+ )).setColor(member.getColor()).queue(channel);
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/HelpCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/HelpCommand.java
index 73d0e8d..c5edbae 100644
--- a/src/main/java/io/rixa/bot/commands/cmds/general/HelpCommand.java
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/HelpCommand.java
@@ -4,7 +4,10 @@ import io.rixa.bot.commands.Command;
import io.rixa.bot.commands.perms.RixaPermission;
import io.rixa.bot.utils.MessageFactory;
import net.dv8tion.jda.core.EmbedBuilder;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.Message;
+import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.core.exceptions.ErrorResponseException;
import net.dv8tion.jda.core.exceptions.PermissionException;
@@ -16,24 +19,21 @@ public class HelpCommand extends Command {
}
@Override
- public void execute(GuildMessageReceivedEvent event) {
- try {
- event.getMessage().delete().complete();
- } catch (PermissionException ignored) {}
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
EmbedBuilder embedBuilder = new EmbedBuilder();
String stringBuilder = "\u2753" +
" **Help**" +
"\n" +
"Click the corresponding number for more information about the command menu.";
- embedBuilder.setTitle(String.format("Help: %s", event.getGuild().getId()))
+ embedBuilder.setTitle(String.format("Help: %s", guild.getId()))
.setDescription(stringBuilder)
.addField("1 - General Commands", "Reveals usable commands intended for `everyone`", false)
.addField("2 - Staff Commands", "Reveals usable commands intended for `staff` use only", false)
.addField("3 - Music Commands", "Reveals usable commands to configure Rixa for your discord!", false)
- .setColor(event.getMember().getColor());
- Message message = event.getAuthor().openPrivateChannel().complete().sendMessage(embedBuilder.build()).complete();
- MessageFactory.create(event.getMember().getAsMention()
- + ", the help menu has been private messaged to you!").setColor(event.getMember().getColor()).queue(event.getChannel());
+ .setColor(member.getColor());
+ Message message = member.getUser().openPrivateChannel().complete().sendMessage(embedBuilder.build()).complete();
+ MessageFactory.create(member.getAsMention()
+ + ", the help menu has been private messaged to you!").setColor(member.getColor()).queue(channel);
try {
message.addReaction("\u0031\u20E3").queue();
message.addReaction("\u0032\u20E3").queue();
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/InfoCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/InfoCommand.java
index aab5a2e..0cd5ba0 100644
--- a/src/main/java/io/rixa/bot/commands/cmds/general/InfoCommand.java
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/InfoCommand.java
@@ -8,15 +8,14 @@ import io.rixa.bot.utils.MessageFactory;
import net.dv8tion.jda.core.EmbedBuilder;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDAInfo;
-import net.dv8tion.jda.core.entities.Member;
-import net.dv8tion.jda.core.entities.Message;
-import net.dv8tion.jda.core.entities.MessageEmbed;
-import net.dv8tion.jda.core.entities.User;
+import net.dv8tion.jda.core.entities.*;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.concurrent.TimeUnit;
public class InfoCommand extends Command {
@@ -26,33 +25,32 @@ public class InfoCommand extends Command {
}
@Override
- public void execute(GuildMessageReceivedEvent event) {
- System.out.println("INFO COMMAND TRIGGERED");
- String[] messages = event.getMessage().getContent().split(" ");
- System.out.println(messages.length);
- if(messages.length >= 2) {
- Member member = DiscordUtils.memberSearch(event.getGuild(), event.getMessage().getContent(), false).get(0);
+ public void execute(String commandLabel, Guild guild, Member author, TextChannel channel, String[] args) {
+ if(args.length >= 1) {
+ Member member = DiscordUtils.memberSearch(guild, String.join(" ", args), false).get(0);
User user = member.getUser();
OffsetDateTime time = user.getCreationTime();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM/dd/yyyy HH:mm:ss");
+ List roles = new ArrayList<>();
+ member.getRoles().forEach(role -> roles.add(role.getName()));
MessageFactory.create("Playing **" + (member.getGame() == null ? "Unknown" : member.getGame().getName()) + "**")
.setColor(member.getColor())
.setThumbnail(user.getAvatarUrl())
.setAuthor("User Information: " + user.getName(), null, user.getAvatarUrl())
.addField("User", user.getAsMention(), true)
.addField("ID", user.getId(), true)
- .addField("Roles", String.valueOf(member.getRoles().size()), true)
+ .addField("Roles: "+ member.getRoles().size(), String.join(" **,** " + roles), true)
.addField("Status", member.getOnlineStatus().name(), true)
.addField("Mutual Guilds", String.valueOf(user.getMutualGuilds().size()), true)
.addField("Nickname", member.getNickname() == null ? "None" : member.getNickname(), true)
.addField("Created", time.format(formatter), true)
.addField("Joined", member.getJoinDate().format(formatter), true)
- .queue(event.getChannel());
+ .queue(channel);
return;
}
- User botOwner = event.getJDA().getUserById("202944101333729280");
+ User botOwner = guild.getJDA().getUserById("202944101333729280");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
- Date date1 = new Date(Rixa.getTimeUp());
+ Date date1 = new Date(Rixa.getInstance().getTimeUp());
long difference = new Date().getTime() - date1.getTime();
long seconds = difference / 1000;
int day = (int) TimeUnit.SECONDS.toDays(seconds);
@@ -71,13 +69,14 @@ public class InfoCommand extends Command {
"levels, and more. Rixa was created to bring ease and simplicity to managing Discord servers, and has since grown into much more than just a bot used for " +
"moderation.")
.setTitle("Rixa Discord Bot", "http://rixa.io/")
- .addField("Created", event.getJDA().getSelfUser().getCreationTime().format(formatter), true)
+ .addField("Created", guild.getJDA().getSelfUser().getCreationTime().format(formatter), true)
.addField("Bot Uptime ", uptime, true)
.addField("Total Guilds", String.valueOf(guildCount), true)
.addField("Total Users", String.valueOf(userCount), true)
.addField("JDA Version", JDAInfo.VERSION, true)
.addField("Rixa Developer", botOwner.getName() + "#" + botOwner.getDiscriminator(), true)
- .footer("Requested by " + event.getAuthor().getName() + "#" + event.getAuthor().getDiscriminator(), event.getAuthor().getAvatarUrl())
- .queue(event.getChannel());
+ .footer("Requested by " + author.getUser().getName() + "#" + author.getUser().getDiscriminator(), author.getUser().getAvatarUrl())
+ .queue(channel);
}
+
}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/MinecraftCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/MinecraftCommand.java
new file mode 100644
index 0000000..711cd7a
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/MinecraftCommand.java
@@ -0,0 +1,60 @@
+package io.rixa.bot.commands.cmds.general;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.utils.MessageFactory;
+import io.rixa.bot.utils.WebUtil;
+import net.dv8tion.jda.core.entities.Channel;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.util.List;
+
+public class MinecraftCommand extends Command {
+
+ public MinecraftCommand(String command, RixaPermission rixaPermission, String description, Listaliases) {
+ super(command, rixaPermission, description, aliases);
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ if (args.length == 0) {
+ MessageFactory.create("Incorrect Usage! Try " + args[0] + " {IP}:{PORT}").setColor(member.getColor()).queue(channel);
+ return;
+ }
+
+ String ipAddress = args[1];
+
+ JSONObject object = get(ipAddress);
+ if (object == null || !object.getBoolean("status")) {
+ // Not correct
+ MessageFactory.create("Server Information not found!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ JSONObject onlineObject = object.getJSONObject("players");
+ MessageFactory.create(
+ object.getJSONObject("motds").getString("clean"))
+ .setTitle(ipAddress)
+ .addField("Version", object.getString("version"), true)
+ .addField("Online Players", (onlineObject == null) ? "0/0" : onlineObject.getInt("online") + "/" + onlineObject.getInt("max"), true)
+ .addField("Ping", String.valueOf(object.getInt("ping")), true)
+ .setImage(String.format("https://use.gameapis.net/mc/query/banner/%s/night,caps", ipAddress))
+ .addThumbnail("https://use.gameapis.net/mc/query/icon/" + ipAddress)
+ .queue(channel);
+ }
+
+ private JSONObject get(String ip) {
+ String json;
+ try {
+ json = WebUtil.getWebPage("https://use.gameapis.net/mc/query/info/" + ip);
+ } catch (IOException e) {
+ return null;
+ }
+ return new JSONObject(json);
+ }
+
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/ModulesCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/ModulesCommand.java
new file mode 100644
index 0000000..7a0f2ff
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/ModulesCommand.java
@@ -0,0 +1,32 @@
+package io.rixa.bot.commands.cmds.general;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.manager.GuildManager;
+import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ModulesCommand extends Command {
+
+ public ModulesCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild);
+ List modules = new ArrayList<>();
+ rixaGuild.getModules().values().forEach
+ (module -> modules.add(String.format("%s [%s]", module.getName(), (module.isEnabled()) ? "Enabled" : "Disabled")));
+ String moduleMessage = String.format(
+ "Modules: \n%s",
+ String.join(",\n", modules));
+ MessageFactory.create(moduleMessage).setColor(member.getColor()).setThumbnail(guild.getIconId()).queue(channel);
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/MusicCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/MusicCommand.java
new file mode 100644
index 0000000..1eacdca
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/MusicCommand.java
@@ -0,0 +1,344 @@
+package io.rixa.bot.commands.cmds.general;
+
+import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
+import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
+import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
+import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
+import com.sedmelluq.discord.lavaplayer.source.bandcamp.BandcampAudioSourceManager;
+import com.sedmelluq.discord.lavaplayer.source.beam.BeamAudioSourceManager;
+import com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager;
+import com.sedmelluq.discord.lavaplayer.source.local.LocalAudioSourceManager;
+import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioSourceManager;
+import com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager;
+import com.sedmelluq.discord.lavaplayer.source.vimeo.VimeoAudioSourceManager;
+import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager;
+import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
+import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
+import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
+import io.rixa.bot.apis.YoutubeSearch;
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.manager.GuildManager;
+import io.rixa.bot.guild.modules.module.MusicModule;
+import io.rixa.bot.guild.modules.module.music.MusicManager;
+import io.rixa.bot.pagination.QueuePagination;
+import io.rixa.bot.utils.DiscordUtils;
+import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.MessageBuilder;
+import net.dv8tion.jda.core.Permission;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.entities.VoiceChannel;
+import net.dv8tion.jda.core.exceptions.PermissionException;
+import org.apache.commons.lang3.StringUtils;
+
+import java.awt.*;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class MusicCommand extends Command {
+
+ private final int DEFAULT_VOLUME = 35;
+ private final AudioPlayerManager playerManager;
+
+ public MusicCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ this.playerManager = new DefaultAudioPlayerManager();
+ this.playerManager.registerSourceManager(new YoutubeAudioSourceManager());
+ this.playerManager.registerSourceManager(new SoundCloudAudioSourceManager());
+ this.playerManager.registerSourceManager(new BandcampAudioSourceManager());
+ this.playerManager.registerSourceManager(new VimeoAudioSourceManager());
+ this.playerManager.registerSourceManager(new TwitchStreamAudioSourceManager());
+ this.playerManager.registerSourceManager(new HttpAudioSourceManager());
+ this.playerManager.registerSourceManager(new LocalAudioSourceManager());
+ this.playerManager.registerSourceManager(new BeamAudioSourceManager());
+
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild);
+ MusicManager musicManager = getMusicManager(rixaGuild);
+ AudioPlayer player = musicManager.getPlayer();
+ QueuePagination queuePagination = musicManager.getScheduler().getQueuePagination();
+ if (args.length == 1) {
+ switch (args[0].toLowerCase()) {
+ case "leave":
+ MessageFactory.create("Leaving voice channel...").setColor(member.getColor()).queue(channel);
+ reset(guild, musicManager);
+ channel.getGuild().getAudioManager().closeAudioConnection();
+ break;
+ case "join":
+ case "summon":
+ if (member.getVoiceState().getChannel() == null) {
+ MessageFactory.create("You must be in a voice channel to summon me!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ VoiceChannel voiceChannel = member.getVoiceState().getChannel();
+ joinVoice(voiceChannel, member, channel);
+ break;
+ case "pause":
+ case "resume":
+ case "play":
+ if (player.isPaused()) {
+ player.setPaused(false);
+ MessageFactory.create("MusicPlayer resumed track: " + player.getPlayingTrack().getInfo().title).setColor(member.getColor()).queue(channel);
+ } else if (!(player.isPaused())) {
+ player.setPaused(false);
+ MessageFactory.create("MusicPlayer paused track: " + player.getPlayingTrack().getInfo().title).setColor(member.getColor()).queue(channel);
+ } else if (player.getPlayingTrack() != null) {
+ MessageFactory.create("MusicPlayer already playing track: " + player.getPlayingTrack().getInfo().title).setColor(member.getColor()).queue(channel);
+ } else if (musicManager.getScheduler().getQueue().isEmpty()) {
+ MessageFactory.create("The audio queue is empty! Add a track to the queue first!").setColor(member.getColor()).queue(channel);
+ }
+ break;
+ case "stop":
+ musicManager.getScheduler().getQueue().clear();
+ player.stopTrack();
+ player.setPaused(false);
+ MessageFactory.create("The music player has been stopped and queue has been cleared.").setColor(member.getColor()).queue(channel);
+ break;
+ case "skip":
+ AudioTrack audioTrack = musicManager.getScheduler().nextTrack();
+ if (audioTrack == null) {
+ MessageFactory.create("The queue is now empty, add more to continue to listen to music!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ MessageFactory.create("Successfully skipped current track. Now playing: " + audioTrack.getInfo().title).setColor(member.getColor()).queue(channel);
+ break;
+ case "nowplaying":
+ case "np":
+ audioTrack = musicManager.getScheduler().getPlayer().getPlayingTrack();
+ if (audioTrack == null) {
+ MessageFactory.create("The audio queue is empty! Add a track to the queue first!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ MessageFactory.create().setAuthor(audioTrack.getInfo().title, "https://i.imgur.com/lOoybhD.png")
+ .addField("Author", audioTrack.getInfo().author, true)
+ .addField("Duration", getTimestamp(audioTrack.getInfo().length), true)
+ .addField("Position", getTimestamp(audioTrack.getPosition()), true).queue(channel);
+ break;
+ case "playlist":
+ case "queue":
+ case "list":
+ if (musicManager.getScheduler().getQueue().size() == 0) {
+ MessageFactory.create("The audio queue is empty! Add a track to the queue first!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ List firstPage = queuePagination.getPage(1);
+ if (firstPage == null || firstPage.isEmpty()) {
+ MessageFactory.create("The audio queue is empty! Add a track to the queue first!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ List titles = new ArrayList<>();
+ for (int i = 0; i < firstPage.size(); i++) {
+ if (firstPage.get(i) == null) continue;
+ titles.add("`" + (i + 1) + ")` " + firstPage.get(i).getInfo().title);
+ }
+ MessageFactory.create(String.join("\n", titles)).setAuthor("Music Queue", "https://i.imgur.com/lOoybhD.png").queue(channel);
+ break;
+ case "restart":
+ audioTrack = player.getPlayingTrack();
+ if (audioTrack == null) {
+ audioTrack = musicManager.getScheduler().getLastTrack();
+ }
+ if (audioTrack == null) {
+ MessageFactory.create("No track has been previously played.").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ MessageFactory.create("Restarting Track: " + audioTrack.getInfo().title).setColor(member.getColor()).queue(channel);
+ player.playTrack(audioTrack.makeClone());
+ break;
+ case "repeat":
+ musicManager.getScheduler().setRepeating(!musicManager.getScheduler().isRepeating());
+ MessageFactory.create("Music repeat has been " + (musicManager.getScheduler().isRepeating() ? "enabled" : "disabled"))
+ .setColor(member.getColor()).queue(channel);
+ break;
+ case "playlistrepeat":
+ case "pr":
+ musicManager.getScheduler().setPlaylistRepeat(!musicManager.getScheduler().isPlaylistRepeat());
+ MessageFactory.create("Playlist repeat has been " + (musicManager.getScheduler().isPlaylistRepeat() ? "enabled" : "disabled"))
+ .setColor(member.getColor()).queue(channel);
+ break;
+ case "reset":
+ reset(guild, musicManager);
+ guild.getAudioManager().setSendingHandler(musicManager.getSendHandler());
+ MessageFactory.create("The player has been completely reset!").setColor(member.getColor()).queue(channel);
+ break;
+ case "shuffle":
+ if (musicManager.getScheduler().getQueue().isEmpty()) {
+ MessageFactory.create("The queue is currently empty!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ musicManager.getScheduler().shuffle();
+ MessageFactory.create("The queue has been shuffled!").setColor(member.getColor()).queue(channel);
+ break;
+ }
+ } else if (args.length == 2) {
+ String string = StringUtils.join(args, " ", 1, args.length);
+ switch (args[0].toLowerCase()) {
+ case "join":
+ VoiceChannel voiceChannel = DiscordUtils.voiceChannelSearch(guild, string);
+ if (voiceChannel == null) {
+ return;
+ }
+ joinVoice(voiceChannel, member, channel);
+ break;
+ case "play":
+ case "playlist":
+ case "pplay":
+ if (member.getVoiceState().getChannel() == null) {
+ MessageFactory.create("You must be in a voice channel to summon me!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ if (guild.getSelfMember().getVoiceState().getChannel() == null) {
+ joinVoice(member.getVoiceState().getChannel(), member, channel);
+ }
+ loadAndPlay(musicManager, channel, args[1], (args[1].toLowerCase().contains("playlist")
+ || args[0].equalsIgnoreCase("playlist")
+ || args[0].equalsIgnoreCase("pplay")));
+ break;
+ case "volume":
+ case "vol":
+ try {
+ int newVolume = Math.max(10, Math.min(100, Integer.parseInt(args[1])));
+ int oldVolume = player.getVolume();
+ player.setVolume(newVolume);
+ MessageFactory.create("Music player volume updated from `" + oldVolume + "` to `" + newVolume + "`").setColor(member.getColor()).queue(channel);
+ } catch (NumberFormatException e) {
+ MessageFactory.create(args[1] + " is not a valid integer. Try a number between 10 and 100.").setColor(member.getColor()).queue(channel);
+ }
+ break;
+ case "forward":
+ if (player.getPlayingTrack() == null) {
+ MessageFactory.create("The audio queue is empty! Add a track to the queue first!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ try {
+ player.getPlayingTrack().setPosition(Math.max(0, player.getPlayingTrack().getPosition() + (Integer.parseInt(args[1]) * 1000)));
+ } catch (NumberFormatException e) {
+ MessageFactory.create(args[1] + " is not a valid integer. Try `10`!").setColor(member.getColor()).queue(channel);
+ }
+ break;
+ case "back":
+ if (player.getPlayingTrack() == null) {
+ MessageFactory.create("The audio queue is empty! Add a track to the queue first!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ try {
+ player.getPlayingTrack().setPosition(Math.max(0, player.getPlayingTrack().getPosition() - (Integer.parseInt(args[1]) * 1000)));
+ } catch (NumberFormatException e) {
+ MessageFactory.create(args[1] + " is not a valid integer. Try `10`!").setColor(member.getColor()).queue(channel);
+ }
+ break;
+ }
+ } else if (args.length >= 3) {
+ String string = StringUtils.join(args, " ", 1, args.length);
+ switch (args[0].toLowerCase()) {
+ case "join":
+ VoiceChannel voiceChannel = DiscordUtils.voiceChannelSearch(guild, string);
+ if (voiceChannel == null) {
+ MessageFactory.create("Sorry I was unable to find the VoiceChannel: `" + string + "`.").setColor(member.getColor()).queue(channel);
+ }
+ joinVoice(voiceChannel, member, channel);
+ break;
+ case "youtube":
+ case "ytsearch":
+ case "yt":
+ case "search":
+ try {
+ YoutubeSearch ytSearch = new YoutubeSearch(string);
+ loadAndPlay(musicManager, channel, ytSearch.getUrl(0), false);
+ } catch (IOException e) {
+ MessageFactory.create("Error Occurred: Could not play youtube video.").setColor(member.getColor()).queue(channel);
+ }
+ break;
+ }
+ }
+ }
+
+ private void joinVoice(VoiceChannel voiceChannel, Member member, TextChannel channel) {
+ try {
+ channel.getGuild().getAudioManager().openAudioConnection(voiceChannel);
+ MessageFactory.create("Entering Voice Channel: " + voiceChannel.getName()).setColor(member.getColor()).queue(channel);
+ } catch (PermissionException e) {
+ if (e.getPermission() == Permission.VOICE_CONNECT) {
+ MessageFactory.create("I do not have permission to join the requested voice channel.").setColor(member.getColor()).queue(channel);
+ }
+ }
+ }
+
+ private void reset(Guild guild, MusicManager musicManager) {
+ synchronized (musicManager) {
+ musicManager.getScheduler().getQueue().clear();
+ musicManager.getScheduler().getPlayer().destroy();
+ guild.getAudioManager().setSendingHandler(null);
+ }
+ }
+
+ private void loadAndPlay(MusicManager mng, final TextChannel channel, final String trackUrl, final boolean addPlaylist) {
+ playerManager.loadItemOrdered(mng, trackUrl, new AudioLoadResultHandler() {
+ @Override
+ public void trackLoaded(AudioTrack track) {
+ String msg = "Adding to queue: " + track.getInfo().title;
+ mng.getScheduler().queue(track);
+ MessageFactory.create(msg).setColor(Color.decode("#4CC276")).queue(channel);
+ }
+
+ @Override
+ public void playlistLoaded(AudioPlaylist playlist) {
+ AudioTrack firstTrack = playlist.getSelectedTrack();
+ List tracks = playlist.getTracks();
+
+ if (firstTrack == null) {
+ firstTrack = playlist.getTracks().get(0);
+ }
+
+ if (addPlaylist) {
+ MessageFactory.create("Adding (" + playlist.getTracks().size() + ") tracks to queue from playlist: " + playlist.getName()).setColor(Color.decode("#4CC276")).queue(channel);
+ tracks.forEach(mng.getScheduler()::queue);
+ } else {
+ MessageFactory.create("Adding to queue " + firstTrack.getInfo().title + " (first track of playlist " + playlist.getName() + ")").setColor(Color.decode("#4CC276")).queue(channel);
+ mng.getScheduler().queue(firstTrack);
+ }
+ }
+
+ @Override
+ public void noMatches() {
+ MessageFactory.create("Nothing found by " + trackUrl).setColor(Color.decode("#4CC276")).queue(channel);
+ }
+
+ @Override
+ public void loadFailed(FriendlyException exception) {
+ MessageFactory.create("Could not play: " + exception.getMessage()).setColor(Color.decode("#4CC276")).queue(channel);
+ exception.printStackTrace();
+ }
+ });
+ }
+
+ public MusicManager getMusicManager(RixaGuild guild) {
+ MusicModule musicModule = (MusicModule) guild.getModule("Music");
+ if (musicModule.getMusicManager() != null) {
+ return musicModule.getMusicManager();
+ }
+ MusicManager musicManager = new MusicManager(this.playerManager);
+ musicManager.getPlayer().setVolume(DEFAULT_VOLUME);
+ musicModule.setMusicManager(musicManager);
+ return musicManager;
+ }
+
+ private String getTimestamp(long milliseconds) {
+ int seconds = (int) (milliseconds / 1000) % 60;
+ int minutes = (int) ((milliseconds / (1000 * 60)) % 60);
+ int hours = (int) ((milliseconds / (1000 * 60 * 60)) % 24);
+
+ if (hours > 0)
+ return String.format("%02d:%02d:%02d", hours, minutes, seconds);
+ else
+ return String.format("%02d:%02d", minutes, seconds);
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/PingCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/PingCommand.java
index 1af1d6f..ed896b9 100644
--- a/src/main/java/io/rixa/bot/commands/cmds/general/PingCommand.java
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/PingCommand.java
@@ -3,6 +3,9 @@ package io.rixa.bot.commands.cmds.general;
import io.rixa.bot.commands.Command;
import io.rixa.bot.commands.perms.RixaPermission;
import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
public class PingCommand extends Command {
@@ -12,7 +15,7 @@ public class PingCommand extends Command {
}
@Override
- public void execute(GuildMessageReceivedEvent event) {
- MessageFactory.create("Pong! [" + event.getJDA().getPing() + "ms]").setColor(event.getMember().getColor()).queue(event.getChannel());
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ MessageFactory.create("Pong! [" + guild.getJDA().getPing() + "ms]").setColor(member.getColor()).queue(channel);
}
}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/QuoteCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/QuoteCommand.java
new file mode 100644
index 0000000..709e804
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/QuoteCommand.java
@@ -0,0 +1,50 @@
+package io.rixa.bot.commands.cmds.general;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.utils.MessageFactory;
+import io.rixa.bot.utils.WebUtil;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
+import org.json.JSONObject;
+
+import java.io.IOException;
+
+public class QuoteCommand extends Command {
+
+ public QuoteCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+
+ }
+
+ public void execute(GuildMessageReceivedEvent event) {
+ String[] quote = getAdvice();
+ MessageFactory.create(quote[0]).setTitle("Author: " + quote[1]).footer("Requested by: " + event.getMember().getEffectiveName(), event.getAuthor().getEffectiveAvatarUrl())
+ .setColor(event.getMember().getColor()).queue(event.getChannel());
+ }
+
+ private String[] getAdvice() {
+ String[] strings = new String[2];
+ String json;
+ try {
+ json = WebUtil.getWebPage("https://api.forismatic.com/api/1.0/?method=getQuote&lang=en&format=json");
+ } catch (IOException e) {
+ strings[0] = "Could not find any quotes for you.";
+ strings[1] = "Author not found";
+ return strings;
+ }
+
+ JSONObject obj = new JSONObject(json);
+ String quote = obj.getString("quoteText");
+ String author = obj.getString("quoteAuthor");
+ strings[0] = quote;
+ strings[1] = author;
+ return strings;
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/RoleMemberList.java b/src/main/java/io/rixa/bot/commands/cmds/general/RoleMemberList.java
new file mode 100644
index 0000000..45e22fc
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/RoleMemberList.java
@@ -0,0 +1,48 @@
+package io.rixa.bot.commands.cmds.general;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.utils.DiscordUtils;
+import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.Role;
+import net.dv8tion.jda.core.entities.TextChannel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RoleMemberList extends Command {
+
+ public RoleMemberList(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ String string = String.join(" ", args);
+ Role role = DiscordUtils.searchFirstRole(guild, string);
+ if (role == null) {
+ MessageFactory.create("Incorrect Usage! Example: " + commandLabel + " Member!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ List roleMembers = guild.getMembersWithRoles(role);
+ if (roleMembers.isEmpty()) {
+ MessageFactory.create("Could not find any users with the role " + role.getName()).setColor(member.getColor()).queue(channel);
+ return;
+ }
+ StringBuilder builder = new StringBuilder("Users With Role `").append(role.getName()).append("`: ");
+ List membersWithRole = new ArrayList<>();
+ roleMembers.forEach(roleMember -> membersWithRole.add(format(roleMember)));
+ builder.append(String.join(", ", membersWithRole));
+ MessageFactory.create(builder.toString().trim()).setColor(member.getColor()).queue(channel);
+ }
+
+ private String format(Member member) {
+ String name = member.getUser().getName() + "#" + member.getUser().getDiscriminator();
+ if (member.getNickname() != null && !member.getNickname().isEmpty()) {
+ name = name + String.format(" [%s]", member.getNickname());
+ }
+ return name;
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/ServerInfoCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/ServerInfoCommand.java
index 32af2c4..9a1eeb2 100644
--- a/src/main/java/io/rixa/bot/commands/cmds/general/ServerInfoCommand.java
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/ServerInfoCommand.java
@@ -5,6 +5,9 @@ import io.rixa.bot.commands.perms.RixaPermission;
import io.rixa.bot.guild.RixaGuild;
import io.rixa.bot.guild.manager.GuildManager;
import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.User;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
@@ -17,25 +20,25 @@ public class ServerInfoCommand extends Command {
}
@Override
- public void execute(GuildMessageReceivedEvent event) {
- RixaGuild rixaGuild = GuildManager.getInstance().getGuild(event.getGuild());
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
- User owner = event.getGuild().getOwner().getUser();
+ User owner = guild.getOwner().getUser();
MessageFactory
.create(rixaGuild.getDescription())
- .setTitle(event.getGuild().getName(), String.format("http://rixa.io/servers/%s", event.getGuild().getId()))
- .addField("Created", event.getGuild().getCreationTime().format(formatter), true)
- .addField("Region", event.getGuild().getRegion().toString(), true)
- .addField("Users", String.valueOf(event.getGuild().getMembers().size()), true)
- .addField("Channel Categories", String.valueOf(event.getGuild().getCategories().size()), true)
- .addField("Text Channels", String.valueOf(event.getGuild().getTextChannels().size()), true)
- .addField("Voice Channels", String.valueOf(event.getGuild().getVoiceChannels().size()), true)
- .addField("Verification Level", event.getGuild().getVerificationLevel().toString(), true)
- .addField("Roles", String.valueOf(event.getGuild().getRoles().size()), true)
+ .setTitle(guild.getName(), String.format("http://rixa.io/servers/%s", guild.getId()))
+ .addField("Created", guild.getCreationTime().format(formatter), true)
+ .addField("Region", guild.getRegion().toString(), true)
+ .addField("Users", String.valueOf(guild.getMembers().size()), true)
+ .addField("Channel Categories", String.valueOf(guild.getCategories().size()), true)
+ .addField("Text Channels", String.valueOf(guild.getTextChannels().size()), true)
+ .addField("Voice Channels", String.valueOf(guild.getVoiceChannels().size()), true)
+ .addField("Verification Level", guild.getVerificationLevel().toString(), true)
+ .addField("Roles", String.valueOf(guild.getRoles().size()), true)
.addField("Owner", owner.getName() + "#" + owner.getDiscriminator(), true)
.addField("Enlisted", String.valueOf(true), true)
- .setThumbnail(event.getGuild().getIconUrl())
- .footer("Server Id: " + event.getGuild().getId(), event.getGuild().getIconUrl())
- .queue(event.getChannel());
+ .setThumbnail(guild.getIconUrl())
+ .footer("Server Id: " + guild.getId(), guild.getIconUrl())
+ .queue(channel);
}
}
\ No newline at end of file
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/UrbanDictionaryCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/UrbanDictionaryCommand.java
new file mode 100644
index 0000000..c3d3c22
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/UrbanDictionaryCommand.java
@@ -0,0 +1,39 @@
+package io.rixa.bot.commands.cmds.general;
+
+import io.rixa.bot.apis.UrbanDictionary;
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.MessageBuilder;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+public class UrbanDictionaryCommand extends Command {
+
+ public UrbanDictionaryCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) throws IOException {
+ String searchQuery = String.join(" ", args);
+ UrbanDictionary urbanDictionary = null;
+ try {
+ urbanDictionary = new UrbanDictionary(URLEncoder.encode(searchQuery, "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ if(urbanDictionary == null || !urbanDictionary.search()) {
+ MessageFactory.create("Search term not found.").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ MessageFactory.create(urbanDictionary.getDefinition()).setAuthor(
+ String.format("Definition: %s", urbanDictionary.getWordToSearch()),
+ "https://s-media-cache-ak0.pinimg.com/originals/f2/aa/37/f2aa3712516cfd0cf6f215301d87a7c2.jpg").setColor(member.getColor()).queue(channel);
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/YoutubeCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/YoutubeCommand.java
new file mode 100644
index 0000000..636f600
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/general/YoutubeCommand.java
@@ -0,0 +1,29 @@
+package io.rixa.bot.commands.cmds.general;
+
+import io.rixa.bot.apis.YoutubeSearch;
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+
+import java.io.IOException;
+
+public class YoutubeCommand extends Command {
+
+ public YoutubeCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ String searchQuery = String.join(" ", args);
+ try {
+ YoutubeSearch ytSearch = new YoutubeSearch(searchQuery);
+ channel.sendMessage(ytSearch.getUrl(0)).queue();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/moderator/ClearCommand.java b/src/main/java/io/rixa/bot/commands/cmds/moderator/ClearCommand.java
new file mode 100644
index 0000000..c923f31
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/moderator/ClearCommand.java
@@ -0,0 +1,76 @@
+package io.rixa.bot.commands.cmds.moderator;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.manager.GuildManager;
+import io.rixa.bot.user.RixaUser;
+import io.rixa.bot.utils.MessageFactory;
+import io.rixa.bot.utils.Utils;
+import lombok.Getter;
+import net.dv8tion.jda.core.Permission;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.Message;
+import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.exceptions.PermissionException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClearCommand extends Command {
+
+ @Getter
+ private RixaPermission rixaPermission;
+ public ClearCommand(String command, RixaPermission rixaPermission, String description, List aliases) {
+ super(command, rixaPermission, description, aliases);
+ this.rixaPermission = rixaPermission;
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild);
+ if (args == null || args.length == 0 || !Utils.isInteger(args[0])) {
+ MessageFactory.create(String.format("Incorrect Usage! Example: `%s%s 10`", rixaGuild.getSettings().getPrefix(),
+ commandLabel)).setColor(member.getColor()).queue(channel);
+ return;
+ }
+ RixaUser user = new RixaUser();
+ if (!(user.hasPermission(rixaPermission))) {
+ MessageFactory.create("Sorry! You do not have permission for this command!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ int amount = Integer.parseInt(args[0]);
+ if (amount < 1 || amount > 100) {
+ MessageFactory.create("Please try a number less than 100 and greater than 1 and :grimacing:").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ int i = deleteMessages(channel, amount);
+ MessageFactory.create("Successfully deleted *" + i + "* messages in " + channel.getAsMention())
+ .footer("Requested by: " + member.getEffectiveName(), member.getUser().getEffectiveAvatarUrl())
+ .setColor(member.getColor())
+ .queue(channel);
+ }
+
+ private int deleteMessages(TextChannel channel, int amount) {
+ List messageHistory= channel.getHistory().retrievePast(amount).complete();
+ List pinnedMessages = channel.getPinnedMessages().complete();
+ List newMessages = new ArrayList<>();
+ int i = 0;
+ messageHistory.forEach(message -> {
+ if (!(pinnedMessages.contains(message))) {
+ newMessages.add(message);
+ }
+ });
+ // !mute Savvy 10s Hello Savvy!
+ try {
+ channel.deleteMessages(newMessages).queue();
+ i++;
+ } catch (PermissionException ex) {
+ if (ex.getPermission() == Permission.MESSAGE_MANAGE)
+ MessageFactory.create("I do not have permission to clear messages within this channel!").queue(channel);
+ } catch (IllegalArgumentException ignored) {
+ }
+ return i;
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/moderator/MuteCommand.java b/src/main/java/io/rixa/bot/commands/cmds/moderator/MuteCommand.java
new file mode 100644
index 0000000..fc6f44b
--- /dev/null
+++ b/src/main/java/io/rixa/bot/commands/cmds/moderator/MuteCommand.java
@@ -0,0 +1,41 @@
+package io.rixa.bot.commands.cmds.moderator;
+
+import io.rixa.bot.commands.Command;
+import io.rixa.bot.commands.perms.RixaPermission;
+import io.rixa.bot.utils.DiscordUtils;
+import io.rixa.bot.utils.MessageFactory;
+import io.rixa.bot.utils.Utils;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
+
+public class MuteCommand extends Command {
+
+ private RixaPermission rixaPermission;
+ public MuteCommand(String command, RixaPermission rixaPermission, String description) {
+ super(command, rixaPermission, description);
+ this.rixaPermission = rixaPermission;
+ }
+
+ @Override
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ // RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild);
+ String argumentString = String.join(" ", args);
+ Object[] objArray = DiscordUtils.memberSearchArray(guild, argumentString, false);
+ if (objArray.length == 0) {
+ MessageFactory.create("Could not find member!").setColor(member.getColor()).queue(channel);
+ }
+ Member targetMember = (Member) objArray[1];
+ String targetMemberName = String.valueOf(objArray[0]);
+ if (targetMember == null) {
+ MessageFactory.create("Could not find member!").setColor(member.getColor()).queue(channel);
+ return;
+ }
+ argumentString = argumentString.replaceFirst(targetMemberName, "").trim();
+ args = argumentString.split(" ");
+ String time = args[0].trim();
+ argumentString = String.join(" ", args).replaceFirst(time, "");
+ long milliseconds = Utils.toMilliSec(time);
+ MessageFactory.create("Duration: " + time + "\nReason: " + argumentString + "\nDuration in Milliseconds: " + milliseconds).queue(channel);
+ }
+}
diff --git a/src/main/java/io/rixa/bot/commands/cmds/other/ShutdownCommand.java b/src/main/java/io/rixa/bot/commands/cmds/other/ShutdownCommand.java
index 289101e..e9cbba8 100644
--- a/src/main/java/io/rixa/bot/commands/cmds/other/ShutdownCommand.java
+++ b/src/main/java/io/rixa/bot/commands/cmds/other/ShutdownCommand.java
@@ -6,6 +6,9 @@ import io.rixa.bot.commands.perms.RixaPermission;
import io.rixa.bot.guild.RixaGuild;
import io.rixa.bot.guild.manager.GuildManager;
import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Member;
+import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
public class ShutdownCommand extends Command {
@@ -15,13 +18,14 @@ public class ShutdownCommand extends Command {
}
@Override
- public void execute(GuildMessageReceivedEvent event) {
- if (!(Rixa.getInstance().getConfiguration().isBotAdmin(event.getAuthor().getId()))) {
- new MessageFactory(event.getMember().getAsMention() + ", you do not have permission for this command.").setColor(event.getMember().getColor()).queue(event.getChannel());
+ public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) {
+ if (!(Rixa.getInstance().getConfiguration().isBotAdmin(member.getUser().getId()))) {
+ new MessageFactory(member.getAsMention()
+ + ", you do not have permission for this command.").setColor(member.getColor()).queue(channel);
return;
}
try {
- MessageFactory.create("Shutting down...").queue(event.getChannel());
+ MessageFactory.create("Shutting down...").selfDestruct(0).queue(channel);
for (RixaGuild rixaGuild : GuildManager.getInstance().getGuilds().values()) {
Thread.sleep(50);
rixaGuild.save();
diff --git a/src/main/java/io/rixa/bot/commands/handler/CommandHandler.java b/src/main/java/io/rixa/bot/commands/handler/CommandHandler.java
index 1230350..d0fa928 100644
--- a/src/main/java/io/rixa/bot/commands/handler/CommandHandler.java
+++ b/src/main/java/io/rixa/bot/commands/handler/CommandHandler.java
@@ -22,7 +22,7 @@ public class CommandHandler {
}
public Command getCommand(String commandName) throws CommandNotFoundException {
- if (commandMap.containsKey(commandName)) return commandMap.get(commandName);
+ if (commandMap.containsKey(commandName.toLowerCase())) return commandMap.get(commandName.toLowerCase());
for(Command command: commandMap.values()) {
if (command.getAliases().contains(commandName)) {
return command;
diff --git a/src/main/java/io/rixa/bot/data/config/Configuration.java b/src/main/java/io/rixa/bot/data/config/Configuration.java
index dd9a267..dcaf70e 100644
--- a/src/main/java/io/rixa/bot/data/config/Configuration.java
+++ b/src/main/java/io/rixa/bot/data/config/Configuration.java
@@ -11,7 +11,7 @@ public class Configuration {
@Getter @Setter private Map sqlCredentials;
@Getter @Setter private List botAdmins;
@Getter @Setter private String token, botGame;
- @Getter @Setter private int shards;
+ @Getter @Setter private int shards = 1;
public Configuration() {}
diff --git a/src/main/java/io/rixa/bot/data/storage/enums/Statements.java b/src/main/java/io/rixa/bot/data/storage/enums/Statements.java
index 2de1ef0..04951e9 100644
--- a/src/main/java/io/rixa/bot/data/storage/enums/Statements.java
+++ b/src/main/java/io/rixa/bot/data/storage/enums/Statements.java
@@ -7,8 +7,8 @@ public enum Statements {
/*
Select statements
*/
- SELECT_CORE("SELECT * FROM `core` WHERE `guild_id` = ?"),
SELECT_MODULE_STATUS("SELECT `{module_name}` FROM `modules` WHERE `guild_id` = ?"),
+ SELECT_ALL_FROM_TABLE("SELECT * FROM `{table_name}` WHERE `guild_id` = ?"),
/*
diff --git a/src/main/java/io/rixa/bot/events/BotJoinListener.java b/src/main/java/io/rixa/bot/events/BotJoinListener.java
index 5606eac..6a4b63a 100644
--- a/src/main/java/io/rixa/bot/events/BotJoinListener.java
+++ b/src/main/java/io/rixa/bot/events/BotJoinListener.java
@@ -8,7 +8,6 @@ public class BotJoinListener {
@SubscribeEvent
public void onJoin(GuildJoinEvent event) {
- System.out.println("GuildJoinEvent Event");
event.getJDA().getGuilds().forEach(guild -> GuildManager.getInstance().addGuild(guild));
}
}
diff --git a/src/main/java/io/rixa/bot/events/MessageListener.java b/src/main/java/io/rixa/bot/events/MessageListener.java
index 2531cf6..59b8382 100644
--- a/src/main/java/io/rixa/bot/events/MessageListener.java
+++ b/src/main/java/io/rixa/bot/events/MessageListener.java
@@ -12,11 +12,12 @@ import net.dv8tion.jda.core.events.ReadyEvent;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.core.hooks.SubscribeEvent;
+import java.io.IOException;
+
public class MessageListener {
@SubscribeEvent
public void onMessage(GuildMessageReceivedEvent event) {
- System.out.println("GuildMessageReceivedEvent Event");
String message = event.getMessage().getContent().trim();
RixaGuild rixaGuild = GuildManager.getInstance().getGuild(event.getGuild());
if (message.startsWith("@" + event.getGuild().getSelfMember().getEffectiveName())) {
@@ -25,16 +26,21 @@ public class MessageListener {
}
String prefix = "!";
if (!(message.startsWith(prefix))) return;
- String commandName = (message.contains(" ") ? message.split(" ")[0] : message);
- command(commandName, prefix, event);
+ String[] msgArgs = message.split(" ");
+ String commandName = (message.contains(" ") ? msgArgs[0] : message);
+ String[] args = new String[msgArgs.length - 1];
+ System.arraycopy(msgArgs, 1, args, 0, msgArgs.length - 1);
+ command(commandName, prefix, event, args);
}
- private void command(String commandName, String prefix, GuildMessageReceivedEvent event) {
+ private void command(String commandName, String prefix, GuildMessageReceivedEvent event, String[] args) {
commandName = commandName.replaceFirst(prefix, "");
try {
Command command = Rixa.getInstance().getCommandHandler().getCommand(commandName);
- command.execute(event);
- } catch (CommandNotFoundException ignored) {}
+ //command.execute(event);
+ event.getMessage().delete().queue();
+ command.execute(commandName, event.getGuild(), event.getMember(), event.getChannel(), args);
+ } catch (CommandNotFoundException | IOException ignored) { }
}
private void chatter(RixaGuild rixaGuild, TextChannel channel, String message) {
diff --git a/src/main/java/io/rixa/bot/events/UserListener.java b/src/main/java/io/rixa/bot/events/UserListener.java
new file mode 100644
index 0000000..7c5fb63
--- /dev/null
+++ b/src/main/java/io/rixa/bot/events/UserListener.java
@@ -0,0 +1,85 @@
+package io.rixa.bot.events;
+
+import io.rixa.bot.Rixa;
+import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.manager.GuildManager;
+import io.rixa.bot.utils.MessageFactory;
+import net.dv8tion.jda.core.JDA;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.Message;
+import net.dv8tion.jda.core.entities.MessageEmbed;
+import net.dv8tion.jda.core.entities.MessageReaction;
+import net.dv8tion.jda.core.events.guild.member.GuildMemberJoinEvent;
+import net.dv8tion.jda.core.events.guild.member.GuildMemberLeaveEvent;
+import net.dv8tion.jda.core.events.message.priv.PrivateMessageReceivedEvent;
+import net.dv8tion.jda.core.events.message.priv.react.PrivateMessageReactionAddEvent;
+import net.dv8tion.jda.core.hooks.SubscribeEvent;
+
+public class UserListener {
+
+ @SubscribeEvent
+ public void onJoin(GuildMemberJoinEvent event) {
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(event.getGuild());
+ if (!rixaGuild.getSettings().getJoinMessage().equalsIgnoreCase("default_value")) {
+ MessageFactory.create(rixaGuild.getSettings().getJoinMessage()
+ .replace("%guild%", event.getGuild().getName())
+ .replace("%user%", event.getUser().getName())
+ .replace("%joinPosition%", String.valueOf(event.getGuild().getMembers().size())))
+ .selfDestruct(0).send(event.getUser());
+ }
+ if (!rixaGuild.getSettings().isJoinVerification()) {
+ return;
+ }
+ if (!rixaGuild.getConfirmationUsers().contains(event.getUser().getId())) {
+ rixaGuild.getConfirmationUsers().add(event.getUser().getId());
+ }
+ MessageFactory.create(rixaGuild.getSettings().getJoinPrivateMessage()
+ .replace("%guild%", event.getGuild().getName())
+ .replace("%user%", event.getUser().getName())
+ .replace("%joinPosition%", String.valueOf(event.getGuild().getMembers().size())))
+ .selfDestruct(0).addReaction("thumbsUp").addReaction("thumbsDown").send(event.getUser());
+ }
+
+ @SubscribeEvent
+ public void onAddReactionPM(PrivateMessageReactionAddEvent event) {
+ if (event.getUser().isBot()) return;
+ String messageId = event.getMessageId();
+ Message message = event.getChannel().getMessageById(messageId).complete();
+ if (message == null || message.getEmbeds().size() == 0) return;
+ if (!event.getReaction().getReactionEmote().getName().contains("thumbsUp") &&
+ !event.getReaction().getReactionEmote().getName().contains("thumbsDown")) {
+ System.out.println("Neither reaction added although this was: " + event.getReaction().getReactionEmote().getName());
+ return;
+ }
+ // Add check to see if reaction added is a thumbs up or down
+ MessageEmbed messageEmbed = message.getEmbeds().get(0);
+ if (messageEmbed.getFooter() == null || messageEmbed.getFooter().getText().isEmpty()) return;
+ String guildId = messageEmbed.getFooter().getText();
+ Guild guild = null;
+ for (JDA jda : Rixa.getInstance().getShardList()) {
+ if (jda.getGuildById(guildId) != null) {
+ guild = jda.getGuildById(guildId);
+ }
+ }
+ if (guild == null) return;
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild);
+ if (!rixaGuild.getConfirmationUsers().contains(event.getUser().getId())) return;
+ rixaGuild.getConfirmationUsers().remove(event.getUser().getId());
+ guild.getController().addRolesToMember(guild.getMember(event.getUser()), rixaGuild.getSettings().getDefaultRole()).queue();
+ }
+
+ @SubscribeEvent
+ public void onQuit(GuildMemberLeaveEvent event) {
+ RixaGuild rixaGuild = GuildManager.getInstance().getGuild(event.getGuild());
+ if (rixaGuild.getConfirmationUsers().contains(event.getUser().getId())) {
+ rixaGuild.getConfirmationUsers().remove(event.getUser().getId());
+ }
+ if (!rixaGuild.getSettings().getJoinMessage().equalsIgnoreCase("default_value")) {
+ MessageFactory.create(rixaGuild.getSettings().getQuitMessage()
+ .replace("%guild%", event.getGuild().getName())
+ .replace("%user%", event.getUser().getName())
+ .replace("%joinPosition%", String.valueOf(event.getGuild().getMembers().size())))
+ .selfDestruct(0).send(event.getUser());
+ }
+ }
+}
diff --git a/src/main/java/io/rixa/bot/guild/RixaGuild.java b/src/main/java/io/rixa/bot/guild/RixaGuild.java
index 3caa144..e39009a 100644
--- a/src/main/java/io/rixa/bot/guild/RixaGuild.java
+++ b/src/main/java/io/rixa/bot/guild/RixaGuild.java
@@ -1,9 +1,10 @@
package io.rixa.bot.guild;
-import io.rixa.bot.Rixa;
import io.rixa.bot.guild.manager.IGuild;
import io.rixa.bot.guild.modules.RixaModule;
import io.rixa.bot.guild.modules.module.ConversationModule;
+import io.rixa.bot.guild.modules.module.MusicModule;
+import io.rixa.bot.guild.settings.Settings;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.core.entities.Guild;
@@ -16,22 +17,29 @@ import java.util.Map;
public class RixaGuild implements IGuild {
@Getter private final Map modules;
+ @Getter private List confirmationUsers;
@Getter @Setter private List keywords;
@Getter @Setter private String description;
@Getter private final String id;
@Getter private Guild guild;
+ @Getter private Settings settings;
public RixaGuild(Guild guild) {
this.guild = guild;
id = guild.getId();
modules = new HashMap<>();
keywords = new ArrayList<>();
+ confirmationUsers = new ArrayList<>();
load();
}
@Override
public void load() {
- registerModule(new ConversationModule("Conversation", "Have a conversation with Rixa!"));
+ registerModules(
+ new ConversationModule("Conversation", "Have a conversation with Rixa!", this),
+ new MusicModule("Music", "Listen to music from within discord!", this)
+ );
+ settings = new Settings(this);
}
@Override
@@ -42,6 +50,11 @@ public class RixaGuild implements IGuild {
return modules.get(id);
}
+ private void registerModules(RixaModule... modules) {
+ for (RixaModule module : modules) {
+ registerModule(module);
+ }
+ }
@Override
public RixaModule registerModule(RixaModule module) {
if (!(isRegistered(module.getName()))) modules.put(module.getName(), module);
diff --git a/src/main/java/io/rixa/bot/guild/manager/GuildManager.java b/src/main/java/io/rixa/bot/guild/manager/GuildManager.java
index 677e8ef..fea62a2 100644
--- a/src/main/java/io/rixa/bot/guild/manager/GuildManager.java
+++ b/src/main/java/io/rixa/bot/guild/manager/GuildManager.java
@@ -1,9 +1,9 @@
package io.rixa.bot.guild.manager;
-import gnu.trove.map.TByteByteMap;
import io.rixa.bot.data.storage.DatabaseAdapter;
import io.rixa.bot.data.storage.enums.Statements;
import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.mapper.GuildMapper;
import net.dv8tion.jda.core.entities.Guild;
import java.util.HashMap;
@@ -44,7 +44,7 @@ public class GuildManager {
RixaGuild rixaGuild = new RixaGuild(guild);
rixaGuildMap.put(guild.getId(), rixaGuild);
DatabaseAdapter.getInstance().get().queryForObject(
- Statements.SELECT_CORE.getStatement(), new Object[] { guild.getId() }, new GuildMapper());
+ Statements.SELECT_ALL_FROM_TABLE.getStatement("{table_name}", "core"), new Object[] { guild.getId() }, new GuildMapper());
return rixaGuild;
}
diff --git a/src/main/java/io/rixa/bot/guild/manager/RixaSettings.java b/src/main/java/io/rixa/bot/guild/manager/RixaSettings.java
new file mode 100644
index 0000000..4b8d9a7
--- /dev/null
+++ b/src/main/java/io/rixa/bot/guild/manager/RixaSettings.java
@@ -0,0 +1,9 @@
+package io.rixa.bot.guild.manager;
+
+public interface RixaSettings {
+
+ String getPrefix();
+
+ void load();
+ void save();
+}
diff --git a/src/main/java/io/rixa/bot/guild/manager/GuildMapper.java b/src/main/java/io/rixa/bot/guild/mapper/GuildMapper.java
similarity index 89%
rename from src/main/java/io/rixa/bot/guild/manager/GuildMapper.java
rename to src/main/java/io/rixa/bot/guild/mapper/GuildMapper.java
index 222513c..fadec3e 100644
--- a/src/main/java/io/rixa/bot/guild/manager/GuildMapper.java
+++ b/src/main/java/io/rixa/bot/guild/mapper/GuildMapper.java
@@ -1,5 +1,7 @@
-package io.rixa.bot.guild.manager;
+package io.rixa.bot.guild.mapper;
+import io.rixa.bot.guild.manager.GuildManager;
+import io.rixa.bot.guild.manager.IGuild;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
diff --git a/src/main/java/io/rixa/bot/guild/modules/RixaModule.java b/src/main/java/io/rixa/bot/guild/modules/RixaModule.java
index 9efdd94..9d05159 100644
--- a/src/main/java/io/rixa/bot/guild/modules/RixaModule.java
+++ b/src/main/java/io/rixa/bot/guild/modules/RixaModule.java
@@ -1,5 +1,8 @@
package io.rixa.bot.guild.modules;
+import io.rixa.bot.Rixa;
+import io.rixa.bot.guild.RixaGuild;
+
public interface RixaModule {
String getName();
@@ -8,4 +11,5 @@ public interface RixaModule {
void load();
void save();
void reload();
+ RixaGuild getGuild();
}
diff --git a/src/main/java/io/rixa/bot/guild/modules/module/ConversationModule.java b/src/main/java/io/rixa/bot/guild/modules/module/ConversationModule.java
index 2144c26..bb0da1c 100644
--- a/src/main/java/io/rixa/bot/guild/modules/module/ConversationModule.java
+++ b/src/main/java/io/rixa/bot/guild/modules/module/ConversationModule.java
@@ -6,6 +6,7 @@ import com.google.code.chatterbotapi.ChatterBotSession;
import com.google.code.chatterbotapi.ChatterBotType;
import io.rixa.bot.data.storage.DatabaseAdapter;
import io.rixa.bot.data.storage.enums.Statements;
+import io.rixa.bot.guild.RixaGuild;
import io.rixa.bot.guild.modules.RixaModule;
import lombok.Getter;
import lombok.Setter;
@@ -16,12 +17,14 @@ public class ConversationModule implements RixaModule {
@Getter private ChatterBotSession chatBotSession;
@Getter private ChatterBot chatBot;
@Getter private String name, description;
+ @Getter private RixaGuild guild;
@Getter @Setter boolean enabled;
- public ConversationModule(String name, String description) {
+ public ConversationModule(String name, String description, RixaGuild guild) {
this.name = name;
this.description = description;
this.enabled = true;
+ this.guild = guild;
}
@Override
diff --git a/src/main/java/io/rixa/bot/guild/modules/module/LevelsModule.java b/src/main/java/io/rixa/bot/guild/modules/module/LevelsModule.java
index b7c8981..31d2d15 100644
--- a/src/main/java/io/rixa/bot/guild/modules/module/LevelsModule.java
+++ b/src/main/java/io/rixa/bot/guild/modules/module/LevelsModule.java
@@ -1,5 +1,6 @@
package io.rixa.bot.guild.modules.module;
+import io.rixa.bot.guild.RixaGuild;
import io.rixa.bot.guild.modules.RixaModule;
import lombok.Getter;
import lombok.Setter;
@@ -8,10 +9,12 @@ public class LevelsModule implements RixaModule {
@Getter private String name, description;
@Getter @Setter boolean enabled;
+ @Getter private RixaGuild guild;
- public LevelsModule(String name, String description) {
+ public LevelsModule(String name, String description, RixaGuild rixaGuild) {
this.name = name;
this.description = description;
+ this.guild = rixaGuild;
}
@Override
diff --git a/src/main/java/io/rixa/bot/guild/modules/module/MusicModule.java b/src/main/java/io/rixa/bot/guild/modules/module/MusicModule.java
new file mode 100644
index 0000000..c3f8032
--- /dev/null
+++ b/src/main/java/io/rixa/bot/guild/modules/module/MusicModule.java
@@ -0,0 +1,55 @@
+package io.rixa.bot.guild.modules.module;
+
+import io.rixa.bot.Rixa;
+import io.rixa.bot.data.storage.DatabaseAdapter;
+import io.rixa.bot.data.storage.enums.Statements;
+import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.manager.GuildManager;
+import io.rixa.bot.guild.modules.RixaModule;
+import io.rixa.bot.guild.modules.module.music.MusicManager;
+import lombok.Getter;
+import lombok.Setter;
+import net.dv8tion.jda.core.entities.Role;
+
+public class MusicModule implements RixaModule {
+
+ @Getter private String name, description;
+ @Getter @Setter private Role musicRole;
+ @Getter @Setter boolean enabled;
+ @Getter @Setter private MusicManager musicManager;
+ @Getter private RixaGuild guild;
+
+ public MusicModule(String name, String description, RixaGuild guild) {
+ this.name = name;
+ this.description = description;
+ this.enabled = true;
+ this.guild = guild;
+ }
+
+ @Override
+ public void load() {
+ setEnabled(DatabaseAdapter.getInstance().get().queryForObject
+ (Statements.SELECT_MODULE_STATUS.getStatement("{module_name}", getName()),
+ new Object[]{name}, (resultSet, i) -> resultSet.getBoolean("enabled")));
+ reload();
+ }
+
+ @Override
+ public void save() {
+ // Check & Set if enabled;
+ DatabaseAdapter.getInstance().get().update("UPDATE `modules` SET `music` = ? WHERE `guild_id` = ?", enabled, guild.getId());
+ DatabaseAdapter.getInstance().get().update("UPDATE `music` SET `music_role` = ? WHERE `guild_id` = ?", musicRole.getId(), guild.getId());
+ }
+
+ @Override
+ public void reload() {
+ if (!isEnabled()) return;
+ DatabaseAdapter.getInstance().get().queryForObject(Statements.SELECT_ALL_FROM_TABLE.getStatement("{table}", "music"),
+ new Object[] { guild.getId() }, (resultSet, i) -> {
+ if (guild.getGuild().getRoleById(resultSet.getString("music_role")) != null) {
+ this.musicRole = guild.getGuild().getRoleById(resultSet.getString("music_role"));
+ }
+ return 0;
+ });
+ }
+}
diff --git a/src/main/java/io/rixa/bot/guild/modules/module/music/AudioPlayerSendHandler.java b/src/main/java/io/rixa/bot/guild/modules/module/music/AudioPlayerSendHandler.java
new file mode 100644
index 0000000..47b8dd3
--- /dev/null
+++ b/src/main/java/io/rixa/bot/guild/modules/module/music/AudioPlayerSendHandler.java
@@ -0,0 +1,44 @@
+package io.rixa.bot.guild.modules.module.music;
+
+import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
+import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame;
+import lombok.Getter;
+import net.dv8tion.jda.core.audio.AudioSendHandler;
+
+public class AudioPlayerSendHandler implements AudioSendHandler {
+ @Getter private final AudioPlayer audioPlayer;
+ private AudioFrame lastFrame;
+
+ /**
+ * @param audioPlayer Audio player to wrap.
+ */
+ public AudioPlayerSendHandler(AudioPlayer audioPlayer) {
+ this.audioPlayer = audioPlayer;
+ }
+
+ @Override
+ public boolean canProvide() {
+ if (lastFrame == null) {
+ lastFrame = audioPlayer.provide();
+ }
+ return lastFrame != null;
+ }
+
+ @Override
+ public byte[] provide20MsAudio() {
+ if (lastFrame == null)
+ {
+ lastFrame = audioPlayer.provide();
+ }
+
+ byte[] data = lastFrame != null ? lastFrame.data : null;
+ lastFrame = null;
+
+ return data;
+ }
+
+ @Override
+ public boolean isOpus() {
+ return true;
+ }
+}
diff --git a/src/main/java/io/rixa/bot/guild/modules/module/music/MusicManager.java b/src/main/java/io/rixa/bot/guild/modules/module/music/MusicManager.java
new file mode 100644
index 0000000..bec212f
--- /dev/null
+++ b/src/main/java/io/rixa/bot/guild/modules/module/music/MusicManager.java
@@ -0,0 +1,32 @@
+package io.rixa.bot.guild.modules.module.music;
+
+import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
+import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
+import lombok.Getter;
+
+public class MusicManager {
+ /**
+ * Audio player for the guild.
+ */
+ @Getter private final AudioPlayer player;
+ /**
+ * Track scheduler for the player.
+ */
+ @Getter private final TrackScheduler scheduler;
+ /**
+ * Wrapper around AudioPlayer to use it as an AudioSendHandler.
+ */
+ @Getter private final AudioPlayerSendHandler sendHandler;
+
+ /**
+ * Creates a player and a track scheduler.
+ *
+ * @param manager Audio player manager to use for creating the player.
+ */
+ public MusicManager(AudioPlayerManager manager) {
+ player = manager.createPlayer();
+ scheduler = new TrackScheduler(player);
+ sendHandler = new AudioPlayerSendHandler(player);
+ player.addListener(scheduler);
+ }
+}
diff --git a/src/main/java/io/rixa/bot/guild/modules/module/music/TrackScheduler.java b/src/main/java/io/rixa/bot/guild/modules/module/music/TrackScheduler.java
new file mode 100644
index 0000000..c53cf1b
--- /dev/null
+++ b/src/main/java/io/rixa/bot/guild/modules/module/music/TrackScheduler.java
@@ -0,0 +1,81 @@
+package io.rixa.bot.guild.modules.module.music;
+
+import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
+import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
+import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
+import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
+import io.rixa.bot.pagination.ObjectPagination;
+import io.rixa.bot.pagination.QueuePagination;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+public class TrackScheduler extends AudioEventAdapter {
+ @Getter @Setter private boolean repeating = false, playlistRepeat = false;
+ @Getter private final AudioPlayer player;
+ @Getter private final Queue queue;
+ @Getter private AudioTrack lastTrack;
+ @Getter private QueuePagination queuePagination;
+
+ /**
+ * @param player The audio player this scheduler uses
+ */
+ public TrackScheduler(AudioPlayer player) {
+ this.player = player;
+ this.queue = new LinkedList<>();
+ queuePagination = new QueuePagination(queue, 5);
+ }
+
+ /**
+ * Add the next track to queue or play right away if nothing is in the queue.
+ *
+ * @param track The track to play or add to queue.
+ */
+ public void queue(AudioTrack track) {
+ // Calling startTrack with the noInterrupt set to true will start the track only if nothing is currently playing. If
+ // something is playing, it returns false and does nothing. In that case the player was already playing so this
+ // track goes to the queue instead.
+ if (!player.startTrack(track, true)) {
+ queue.offer(track);
+ }
+ queuePagination.updateList(queue);
+ }
+
+ /**
+ * Start the next track, stopping the current one if it is playing.
+ */
+ public AudioTrack nextTrack() {
+ // Start the next track, regardless of if something is already playing or not. In case queue was empty, we are
+ // giving null to startTrack, which is a valid argument and will simply stop the player.
+ AudioTrack track = queue.poll();
+ player.startTrack(track, false);
+ queuePagination.updateList(queue);
+ return track;
+ }
+
+ @Override
+ public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
+ this.lastTrack = track;
+ // Only start the next track if the end reason is suitable for it (FINISHED or LOAD_FAILED)
+ if (endReason.mayStartNext) {
+ if (repeating)
+ player.startTrack(lastTrack.makeClone(), false);
+ else {
+ if (playlistRepeat) {
+ queue(lastTrack.makeClone());
+ }
+ nextTrack();
+ }
+ }
+
+ }
+
+ public void shuffle() {
+ Collections.shuffle((List>) queue);
+ queuePagination.updateList(queue);
+ }
+}
diff --git a/src/main/java/io/rixa/bot/guild/settings/Settings.java b/src/main/java/io/rixa/bot/guild/settings/Settings.java
new file mode 100644
index 0000000..82acc70
--- /dev/null
+++ b/src/main/java/io/rixa/bot/guild/settings/Settings.java
@@ -0,0 +1,60 @@
+package io.rixa.bot.guild.settings;
+
+import io.rixa.bot.data.storage.DatabaseAdapter;
+import io.rixa.bot.guild.RixaGuild;
+import io.rixa.bot.guild.manager.RixaSettings;
+import lombok.Getter;
+import lombok.Setter;
+import net.dv8tion.jda.core.entities.Role;
+import net.dv8tion.jda.core.entities.TextChannel;
+import org.springframework.jdbc.core.RowMapper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class Settings implements RixaSettings {
+
+ @Getter @Setter private String prefix, joinMessage, quitMessage, joinPrivateMessage;
+ @Getter @Setter private boolean joinVerification;
+ @Getter @Setter private TextChannel greetings, farewell;
+ @Getter @Setter private Role muteRole, defaultRole;
+ @Getter private RixaGuild rixaGuild;
+
+ public Settings(RixaGuild rixaGuild) {
+ this.rixaGuild = rixaGuild;
+ }
+
+ @Override
+ public void load() {
+ DatabaseAdapter.getInstance().get().query("SELECT * FROM `settings` WHERE `guild_id` = ?",
+ new Object[] { rixaGuild.getId() }, (resultSet, i) -> {
+ setPrefix(resultSet.getString("prefix"));
+ setJoinMessage(resultSet.getString("joinMessage"));
+ setJoinMessage(resultSet.getString("quitMessage"));
+ setJoinPrivateMessage(resultSet.getString("joinPm"));
+ setJoinVerification(resultSet.getBoolean("joinVerification"));
+ String greetingsId = resultSet.getString("greetings");
+ String farewellId = resultSet.getString("farewell");
+ String defaultRoleId = resultSet.getString("defaultRole");
+ String muteRoleId = resultSet.getString("muteRole");
+ if (!greetingsId.equalsIgnoreCase("default_value") && rixaGuild.getGuild().getTextChannelById(greetingsId) != null) {
+ greetings = rixaGuild.getGuild().getTextChannelById(greetingsId);
+ }
+ if (!farewellId.equalsIgnoreCase("default_value") && rixaGuild.getGuild().getTextChannelById(farewellId) != null) {
+ farewell = rixaGuild.getGuild().getTextChannelById(farewellId);
+ }
+ if (!defaultRoleId.equalsIgnoreCase("default_value") && rixaGuild.getGuild().getRoleById(defaultRoleId) != null) {
+ defaultRole = rixaGuild.getGuild().getRoleById(defaultRoleId);
+ }
+ if (!muteRoleId.equalsIgnoreCase("default_value") && rixaGuild.getGuild().getRoleById(muteRoleId) != null) {
+ muteRole = rixaGuild.getGuild().getRoleById(muteRoleId);
+ }
+ return null;
+ });
+ }
+
+ @Override
+ public void save() {
+
+ }
+}
diff --git a/src/main/java/io/rixa/bot/pagination/ObjectPagination.java b/src/main/java/io/rixa/bot/pagination/ObjectPagination.java
new file mode 100644
index 0000000..51bd7f7
--- /dev/null
+++ b/src/main/java/io/rixa/bot/pagination/ObjectPagination.java
@@ -0,0 +1,35 @@
+package io.rixa.bot.pagination;
+
+import lombok.Getter;
+
+import java.util.Collections;
+import java.util.List;
+
+public class ObjectPagination {
+
+ @Getter private List