From 6f155f5bee85c7f90582d906bb2067e80b395164 Mon Sep 17 00:00:00 2001 From: Savvy Date: Sun, 21 Jan 2018 15:10:00 -0500 Subject: [PATCH] Fixed all outstanding issues --- src/main/java/io/rixa/bot/Rixa.java | 53 ++-- .../commands/cmds/admin/ConfigCommand.java | 277 ++++++++++++++++++ .../bot/commands/cmds/admin/PMCommand.java | 7 +- .../commands/cmds/general/AdviceCommand.java | 2 +- .../cmds/general/FeaturesCommand.java | 5 +- .../cmds/general/LeaderboardsCommand.java | 58 ++++ .../cmds/general/MinecraftCommand.java | 4 +- .../commands/cmds/general/ModulesCommand.java | 10 +- .../commands/cmds/general/MusicCommand.java | 28 +- .../commands/cmds/general/QuoteCommand.java | 9 +- .../commands/cmds/general/RankCommand.java | 85 ++++++ .../commands/cmds/general/RoleMemberList.java | 6 +- .../commands/cmds/moderator/ClearCommand.java | 17 +- .../commands/cmds/moderator/MuteCommand.java | 8 +- .../bot/commands/perms/RixaPermission.java | 1 - .../bot/data/storage/DatabaseAdapter.java | 3 +- .../data/storage/enums/DatabaseTables.java | 58 ++++ .../io/rixa/bot/events/MessageListener.java | 100 ++++--- .../io/rixa/bot/events/ReadyListener.java | 28 +- .../java/io/rixa/bot/events/UserListener.java | 136 +++++---- .../java/io/rixa/bot/guild/RixaGuild.java | 85 +++++- .../rixa/bot/guild/enums/PermissionType.java | 7 + .../rixa/bot/guild/manager/GuildManager.java | 1 + .../io/rixa/bot/guild/manager/IGuild.java | 7 + .../io/rixa/bot/guild/modules/RixaModule.java | 2 +- .../modules/module/ConversationModule.java | 4 +- .../guild/modules/module/LevelsModule.java | 56 +++- .../bot/guild/modules/module/MusicModule.java | 26 +- .../modules/module/music/TrackScheduler.java | 7 +- .../io/rixa/bot/guild/settings/Settings.java | 23 +- .../io/rixa/bot/pagination/Pagination.java | 42 +++ .../rixa/bot/pagination/QueuePagination.java | 46 --- src/main/java/io/rixa/bot/user/RixaUser.java | 114 ++++++- .../io/rixa/bot/user/manager/UserManager.java | 42 +++ .../user/mapper/UserPermissionsMapper.java | 31 ++ .../java/io/rixa/bot/utils/DiscordUtils.java | 25 ++ .../io/rixa/bot/utils/MessageFactory.java | 37 ++- 37 files changed, 1194 insertions(+), 256 deletions(-) create mode 100644 src/main/java/io/rixa/bot/commands/cmds/admin/ConfigCommand.java create mode 100644 src/main/java/io/rixa/bot/commands/cmds/general/LeaderboardsCommand.java create mode 100644 src/main/java/io/rixa/bot/commands/cmds/general/RankCommand.java create mode 100644 src/main/java/io/rixa/bot/data/storage/enums/DatabaseTables.java create mode 100644 src/main/java/io/rixa/bot/guild/enums/PermissionType.java create mode 100644 src/main/java/io/rixa/bot/pagination/Pagination.java delete mode 100644 src/main/java/io/rixa/bot/pagination/QueuePagination.java create mode 100644 src/main/java/io/rixa/bot/user/manager/UserManager.java create mode 100644 src/main/java/io/rixa/bot/user/mapper/UserPermissionsMapper.java diff --git a/src/main/java/io/rixa/bot/Rixa.java b/src/main/java/io/rixa/bot/Rixa.java index 946d4e1..d4d7aa7 100644 --- a/src/main/java/io/rixa/bot/Rixa.java +++ b/src/main/java/io/rixa/bot/Rixa.java @@ -2,6 +2,7 @@ package io.rixa.bot; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import io.rixa.bot.commands.cmds.admin.ConfigCommand; import io.rixa.bot.commands.cmds.admin.PMCommand; import io.rixa.bot.commands.cmds.general.*; import io.rixa.bot.commands.cmds.moderator.ClearCommand; @@ -11,13 +12,15 @@ import io.rixa.bot.commands.handler.CommandHandler; import io.rixa.bot.commands.perms.RixaPermission; import io.rixa.bot.data.config.Configuration; import io.rixa.bot.data.storage.DatabaseAdapter; +import io.rixa.bot.data.storage.enums.DatabaseTables; 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.user.RixaUser; +import io.rixa.bot.user.manager.UserManager; import io.rixa.bot.utils.FileUtils; import lombok.Getter; import net.dv8tion.jda.core.AccountType; @@ -25,6 +28,7 @@ import net.dv8tion.jda.core.JDA; import net.dv8tion.jda.core.JDABuilder; import net.dv8tion.jda.core.OnlineStatus; import net.dv8tion.jda.core.entities.Game; +import net.dv8tion.jda.core.entities.Game.GameType; import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.exceptions.RateLimitedException; import net.dv8tion.jda.core.hooks.AnnotatedEventManager; @@ -73,10 +77,9 @@ public class Rixa { } 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())) + .setGame(Game.of(GameType.WATCHING, configuration.getBotGame())) .setEventManager(new AnnotatedEventManager()) .addEventListener(new ReadyListener(), new BotJoinListener(), new MessageListener(), new UserListener()) @@ -90,46 +93,45 @@ public class Rixa { getShardList().add(jda.useSharding(i, configuration.getShards()).buildBlocking()); getLogger().info("Shard #" + (i + 1) + " has been loaded"); Thread.sleep(5000); - } catch (InterruptedException | RateLimitedException | LoginException e) { + } catch (InterruptedException | LoginException e) { e.printStackTrace(); } } - 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(); - }); - })); + Runtime.getRuntime().addShutdownHook(new Thread(() -> + getShardList().forEach(jdaInstance -> { + UserManager.getInstance().getUserMap().values().forEach(RixaUser::save); + jdaInstance.getGuilds().forEach((Guild guild) -> { + System.out.println("Saving " + guild.getName() + ": " + guild.getId()); + RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild); + 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 ClearCommand("clear", RixaPermission.CLEAR_CHAT, "Clear Chat!", Arrays.asList("deleemessages", "cmessages")), + new ConfigCommand("config", RixaPermission.ACCESS_CONFIG, "Access the config menu"), 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 MuteCommand("mute", RixaPermission.MUTE, "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 PMCommand("pm", RixaPermission.PM_MESSAGE, "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 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!")); + new YoutubeCommand("youtube", RixaPermission.NONE, "Search for music on youtube!"), + new LeaderboardsCommand("leaderboards", RixaPermission.NONE, "Look at the levels leaderboards!"), + new RankCommand("rank", RixaPermission.NONE, "Check your rank!")); } private void loadConfiguration() { @@ -142,6 +144,11 @@ public class Rixa { configuration = objectMapper.readValue(file, Configuration.class); logger.info("Configuration successfully loaded."); DatabaseAdapter.getInstance().check(); + Arrays.stream(DatabaseTables.values()).forEach(databaseTables -> { + System.out.println("Checking database table (creating if needed): " + databaseTables.toString()); + DatabaseAdapter.getInstance().get().update(databaseTables.getQuery()); + System.out.println("Done checking " + databaseTables.toString()); + }); } catch (IOException e) { logger.severe("Could not properly load configuration file!."); e.printStackTrace(); @@ -151,8 +158,6 @@ public class Rixa { public Guild getGuildById(String id) { Guild guild = null; for (JDA jda : Rixa.getInstance().getShardList()) { - System.out.println(jda.getShardInfo().toString()); - System.out.println("JDA GUILDS:" + jda.getGuilds().size()); if (jda.getGuilds().size() == 0 || jda.getGuildById(id) == null) continue; guild = jda.getGuildById(id); break; diff --git a/src/main/java/io/rixa/bot/commands/cmds/admin/ConfigCommand.java b/src/main/java/io/rixa/bot/commands/cmds/admin/ConfigCommand.java new file mode 100644 index 0000000..5e79b83 --- /dev/null +++ b/src/main/java/io/rixa/bot/commands/cmds/admin/ConfigCommand.java @@ -0,0 +1,277 @@ +package io.rixa.bot.commands.cmds.admin; + +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.pagination.Pagination; +import io.rixa.bot.user.RixaUser; +import io.rixa.bot.user.manager.UserManager; +import io.rixa.bot.utils.DiscordUtils; +import io.rixa.bot.utils.MessageFactory; +import net.dv8tion.jda.core.entities.*; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ConfigCommand extends Command { + + private Pagination pagination; + public ConfigCommand(String command, RixaPermission rixaPermission, String description) { + super(command, rixaPermission, description); + + pagination = new Pagination(Arrays.asList( + "%pconfig set greetings ; Set channel where greeting messages are announced!", + "%pconfig set farewell ; Set channel where farewell messages are announced!", + "%pconfig set prefix ; Set Rixa's command prefix!", + "%pconfig set defaultRole ; Set role to be assigned when a user joins the server!", + "%pconfig set muteRole ; Set role to be assigned when a user is muted!", + "%pconfig set musicRole ; Set role required to use the music functions! (Not required)", + + /* "%pconfig set twitterCKey ; Set Twitter Consumer Key!", + "%pconfig set twitterCSecret ; Set Twitter Consumer Secret!", + "%pconfig set twitterAToken ; Set Twitter Access Key!", + "%pconfig set twitterASecret ; Set Twitter Access Secret!", + "%config set twitterChannel ; Set the channel for Twitter feed updates!",*/ + + "%pconfig set joinMessage ; Set the greetings message for when a user joins the server!", + "%pconfig set quitMessage ; Set the quit message for when a user leaves the server!", + "%pconfig set joinPm ; Set the message to be private messaged when a user joins!", + "%pconfig set description ; Set your server description!", + "%pconfig addPerm ; Give a role permission to access a command!", + "%pconfig removePerm ; Remove a role's permission to access a command!", + "%pconfig enable ; Enabled a Rixa Module!", + "%pconfig disable ; Disable a Rixa Module!" + ), 6); + } + + @Override + public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) { + RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild); + if (args.length == 1) { + switch (args[0].toLowerCase()) { + case "set": + if (args[1].equalsIgnoreCase("greetings")) { + rixaGuild.getSettings().setGreetings(channel); + MessageFactory.create(channel.getAsMention()).setAuthor("Updated Greetings Channel", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + return; + } else if (args[1].equalsIgnoreCase("farewell")) { + rixaGuild.getSettings().setFarewell(channel); + MessageFactory.create(channel.getAsMention()).setAuthor("Updated Farewell Channel", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + return; + } + } + } + if (args.length < 2) { + sendHelp(member, 1, rixaGuild.getSettings().getPrefix()); + return; + } + String string = join(args, 2, args.length); + Role role; + switch (args[0].toLowerCase()) { + case "set": + if (args[1].equalsIgnoreCase("muteRole") || + args[1].equalsIgnoreCase("musicRole") || + args[1].equalsIgnoreCase("defaultRole")) { + role = DiscordUtils.searchFirstRole(guild, string); + if (role == null) { + MessageFactory.create("Sorry I could not find that role!") + .setColor(member.getColor()).setTimestamp().queue(channel); + // Role not found + return; + } + switch(args[1].toLowerCase()) { + case "muterole": + rixaGuild.getSettings().setMuteRole(role); + break; + case "musicrole": + ((MusicModule) rixaGuild.getModule("Music")).setMusicRole(role); + break; + case "defaultrole": + rixaGuild.getSettings().setDefaultRole(role); + break; + } + // Role set + MessageFactory.create(role.getAsMention()).setAuthor("Updated Role", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("joinMessage")) { + rixaGuild.getSettings().setJoinMessage(string); + MessageFactory.create(string).setAuthor("Updated Join Message", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("quitMessage")) { + rixaGuild.getSettings().setQuitMessage(string); + MessageFactory.create(string).setAuthor("Updated Quit Message", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("joinPm")) { + rixaGuild.getSettings().setJoinPrivateMessage(string); + MessageFactory.create(string).setAuthor("Updated Join Private Message", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("description")) { + rixaGuild.setDescription(string); + MessageFactory.create(string).setAuthor("Updated Guild Server Description", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("prefix")) { + rixaGuild.getSettings().setPrefix(string); + MessageFactory.create(string).setAuthor("Updated Command Prefix", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else { + sendHelp(member, 1, rixaGuild.getSettings().getPrefix()); + return; + } + break; + case "enable": + if (rixaGuild.isRegistered(args[1].toLowerCase())) { + rixaGuild.getModule(args[1].toLowerCase()).setEnabled(true); + MessageFactory.create(args[1].toLowerCase()).setAuthor("Module Enabled", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("joinVerification")) { + rixaGuild.getSettings().setJoinVerification(true); + MessageFactory.create(args[1].toLowerCase()).setAuthor("Module Enabled", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else { + MessageFactory.create(args[1].toLowerCase()).setAuthor("Module Not Found", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } + break; + case "disable": + if (rixaGuild.isRegistered(args[1])) { + rixaGuild.getModule(args[1]).setEnabled(false); + MessageFactory.create(args[1]).setAuthor("Module Disabled", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("joinMessage")) { + rixaGuild.getSettings().setJoinMessage("default_value"); + MessageFactory.create(args[1]).setAuthor("Module Disabled", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("quitMessage")) { + rixaGuild.getSettings().setQuitMessage("default_value"); + MessageFactory.create(args[1]).setAuthor("Module Disabled", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("joinPrivateMessage")) { + rixaGuild.getSettings().setJoinPrivateMessage("default"); + MessageFactory.create(args[1]).setAuthor("Module Disabled", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else if (args[1].equalsIgnoreCase("joinVerification")) { + rixaGuild.getSettings().setJoinVerification(false); + MessageFactory.create(args[1].toLowerCase()).setAuthor("Module Disabled", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } else { + MessageFactory.create(args[1].toLowerCase()).setAuthor("Module Not Found", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + } + break; + case "addperm": + case "aperm": + case "addpermission": + case "addperms": + case "addpermissions": + RixaPermission permission = searchPerms(args); + if (permission == null) { + MessageFactory.create("That permission does not exist!").setColor(member.getColor()).queue(channel); + return; + } + if (args[1].equalsIgnoreCase("role")) { + role = DiscordUtils.searchFirstRole(guild, string); + if (role == null) { + MessageFactory.create("That role does not exist!").setColor(member.getColor()).queue(channel); + return; + } + rixaGuild.addPermission(role.getId(), permission); + MessageFactory.create("Role: " + role.getAsMention() + " | Permission: " + + permission.toString()).setAuthor("Permission Given", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + return; + } + if (args[1].equalsIgnoreCase("user")) { + List targets = DiscordUtils.memberSearch(guild, string, false); + if (targets.isEmpty()) { + MessageFactory.create("Could not find that user!").setColor(member.getColor()).queue(channel); + return; + } + RixaUser targetUser = UserManager.getInstance().getUser(targets.get(0).getUser()); + targetUser.addPermission(guild.getId(), permission); + MessageFactory.create("User: " + targetUser.getUser().getAsMention() + " | Permission: " + + permission.toString()).setAuthor("Permission Given", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + return; + } + MessageFactory.create("Incorrect Usage! Try " + commandLabel + " addPerm !").setColor(member.getColor()) + .queue(channel); + break; + case "removeperm": + case "rperm": + case "removepermissions": + case "removeperms": + permission = searchPerms(args); + if (permission == null) { + MessageFactory.create("That permission does not exist!").setColor(member.getColor()).queue(channel); + return; + } + if (args[1].equalsIgnoreCase("role")) { + role = DiscordUtils.searchFirstRole(guild, string); + if (role == null) { + MessageFactory.create("That role does not exist!").setColor(member.getColor()).queue(channel); + return; + } + rixaGuild.removePermission(role.getId(), permission); + MessageFactory.create("Role: " + role.getAsMention() + " | Permission: " + + permission.toString()).setAuthor("Permission Revoked", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + return; + } + if (args[1].equalsIgnoreCase("user")) { + List targets = DiscordUtils.memberSearch(guild, string, false); + if (targets.isEmpty()) { + MessageFactory.create("Could not find that user!").setColor(member.getColor()).queue(channel); + return; + } + RixaUser targetUser = UserManager.getInstance().getUser(targets.get(0).getUser()); + targetUser.removePermission(guild.getId(), permission); + MessageFactory.create("Role: " + targetUser.getUser().getAsMention() + " | Permission: " + + permission.toString()).setAuthor("Permission Revoked", + guild.getIconUrl()).setColor(member.getColor()).queue(channel); + return; + } + MessageFactory.create("Incorrect Usage! Try " + commandLabel + " addPerm !").setColor(member.getColor()) + .queue(channel); + break; + default: + sendHelp(member, 1, rixaGuild.getSettings().getPrefix()); + break; + } + } + + private void sendHelp(Member member, int page, String prefix) { + List objects = pagination.getPage(page); + MessageFactory messageFactory = MessageFactory.create("\u2699" + " **Config**" + + "\nClick the back or forward reactions to switch between pages.") + .setTitle(String.format("Config: %s", member.getGuild().getId())); + objects.forEach(obj -> { + String object = obj.toString(); + messageFactory.addField(object.split(" ; ")[0].replace("%p", prefix), + object.split(" ; ")[1], false); + }); + messageFactory.footer("Page: (" + page + " / " + (pagination.getMaxPage()) + ")", member.getGuild().getIconUrl()) + .setColor(member.getColor()).selfDestruct(0).send(member.getUser(), success -> + success.addReaction("\u2B05").queue(v -> success.addReaction("\u27A1").queue())); + } + + private RixaPermission searchPerms(String[] args) { + for (String stringInArgs : args) { + for (RixaPermission rixaPermission : RixaPermission.values()) { + if (stringInArgs.equalsIgnoreCase(rixaPermission.toString())) { + return rixaPermission; + } + } + } + return null; + } + + private String join(Object[] obj, int startIndex, int endIndex) { + return StringUtils.join(obj, " ", startIndex, endIndex); + } +} 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 index aa074a7..04ac55a 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/admin/PMCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/admin/PMCommand.java @@ -33,16 +33,19 @@ public class PMCommand extends Command { msg = msg.replaceFirst(role.getAsMention(), "").replaceFirst("@" + role.getName(),""); int usersWithRole = 0; int sendingFailed = 0; + String finalMsg = msg; for (Member memberWithRole : guild.getMembersWithRoles(role)) { try { - memberWithRole.getUser().openPrivateChannel().complete().sendMessage(msg).queue(); + memberWithRole.getUser().openPrivateChannel().queue(privateChannel -> privateChannel.sendMessage(finalMsg).queue()); usersWithRole++; } catch (ErrorResponseException ex) { if (ex.getErrorResponse() == ErrorResponse.CANNOT_SEND_TO_USER) sendingFailed++; } } - MessageFactory.create("```" + msg + "```") + MessageFactory.create(msg) + .setAuthor("Private Message: " + role.getName(), guild.getIconUrl()) + .setTimestamp() .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 index a45a8f8..6a5bfe0 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/general/AdviceCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/general/AdviceCommand.java @@ -21,7 +21,7 @@ public class AdviceCommand extends Command { @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); + .setColor(member.getColor()).setTimestamp().queue(channel); } private String getAdvice() { 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 index 4296ddb..1f10a75 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/general/FeaturesCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/general/FeaturesCommand.java @@ -22,9 +22,8 @@ public class FeaturesCommand extends Command { @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); + String.join("\n", features)).setAuthor("Rixa Features", guild.getIconUrl()) + .setColor(member.getColor()).queue(channel); } } diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/LeaderboardsCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/LeaderboardsCommand.java new file mode 100644 index 0000000..a20ac43 --- /dev/null +++ b/src/main/java/io/rixa/bot/commands/cmds/general/LeaderboardsCommand.java @@ -0,0 +1,58 @@ +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.guild.modules.module.LevelsModule; +import io.rixa.bot.user.RixaUser; +import io.rixa.bot.user.manager.UserManager; +import io.rixa.bot.utils.DiscordUtils; +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 net.dv8tion.jda.core.entities.User; + +import java.util.ArrayList; +import java.util.List; + +public class LeaderboardsCommand extends Command { + + public LeaderboardsCommand(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); + LevelsModule levelsModule = (LevelsModule) rixaGuild.getModule("Levels"); + int page = 1; + List leaderboard = getLeaderboard(rixaGuild, page); + MessageFactory.create(leaderboard.isEmpty() ? "No users found!" : (String.join("\n", leaderboard))) + .setAuthor("Leaderboard: " + guild.getName(), guild.getIconUrl()) + .setColor(member.getColor()) + .queue(channel, message -> { + message.addReaction("\u2B05").complete(); + message.addReaction("\u27A1").complete(); + }).footer("Page: (" + page + " / " + levelsModule.getObjectPagination().getMaxPage() + ")", + member.getGuild().getIconUrl()); + + } + + private List getLeaderboard(RixaGuild rixaGuild, int page) { + LevelsModule levelsModule = (LevelsModule) rixaGuild.getModule("Levels"); + List objects = levelsModule.getObjectPagination().getPage(page); + List leaderboard = new ArrayList<>(); + objects.forEach(s -> { + String[] string = String.valueOf(s).split(":"); + User user = rixaGuild.getGuild().getJDA().getUserById(string[0]); + int exp = Integer.parseInt(string[1]); + leaderboard.add + (user.getName() + "#" + user.getDiscriminator() + " (Lvl. " + + DiscordUtils.getLevelFromExperience(exp) + ")"); + }); + return leaderboard; + } +} 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 index 711cd7a..8a5212d 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/general/MinecraftCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/general/MinecraftCommand.java @@ -23,11 +23,11 @@ public class MinecraftCommand extends Command { @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); + MessageFactory.create("Incorrect Usage! Try " + commandLabel + " {IP}:{PORT}").setColor(member.getColor()).queue(channel); return; } - String ipAddress = args[1]; + String ipAddress = args[0]; JSONObject object = get(ipAddress); if (object == null || !object.getBoolean("status")) { 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 index 7a0f2ff..59b0910 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/general/ModulesCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/general/ModulesCommand.java @@ -7,6 +7,7 @@ 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.Message; import net.dv8tion.jda.core.entities.TextChannel; import java.util.ArrayList; @@ -23,10 +24,9 @@ public class ModulesCommand extends Command { 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); + (module -> modules.add(String.format("%s [%s]", module.getName(), + (module.isEnabled()) ? "Enabled" : "Disabled"))); + MessageFactory.create(String.join(",\n", modules)).setAuthor("Module List", guild.getIconUrl()) + .setTimestamp().setColor(member.getColor()).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 index 1eacdca..c5d7f65 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/general/MusicCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/general/MusicCommand.java @@ -22,10 +22,9 @@ 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.pagination.Pagination; 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; @@ -37,7 +36,6 @@ 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 { @@ -62,9 +60,15 @@ public class MusicCommand extends Command { @Override public void execute(String commandLabel, Guild guild, Member member, TextChannel channel, String[] args) { RixaGuild rixaGuild = GuildManager.getInstance().getGuild(guild); + MusicModule musicModule = (MusicModule) rixaGuild.getModule("Music"); + if (musicModule.getMusicRole() != null && !member.getRoles().contains(musicModule.getMusicRole())) { + MessageFactory.create("You do not have the required music role (" + musicModule.getMusicRole().getName() + + ") to use this command").setTimestamp().setColor(member.getColor()).queue(channel); + return; + } MusicManager musicManager = getMusicManager(rixaGuild); AudioPlayer player = musicManager.getPlayer(); - QueuePagination queuePagination = musicManager.getScheduler().getQueuePagination(); + Pagination queuePagination = musicManager.getScheduler().getQueuePagination(); if (args.length == 1) { switch (args[0].toLowerCase()) { case "leave": @@ -117,7 +121,7 @@ public class MusicCommand extends Command { 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") + MessageFactory.create().setAuthor(audioTrack.getInfo().title, "https://i.imgur.com/AnaMjsH.png") .addField("Author", audioTrack.getInfo().author, true) .addField("Duration", getTimestamp(audioTrack.getInfo().length), true) .addField("Position", getTimestamp(audioTrack.getPosition()), true).queue(channel); @@ -129,7 +133,7 @@ public class MusicCommand extends Command { 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); + 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; @@ -137,9 +141,13 @@ public class MusicCommand extends Command { 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); + titles.add("`" + (i + 1) + ")` " + ((AudioTrack) firstPage.get(i)).getInfo().title); } - MessageFactory.create(String.join("\n", titles)).setAuthor("Music Queue", "https://i.imgur.com/lOoybhD.png").queue(channel); + MessageFactory.create(String.join("\n", titles)).setAuthor("Music Queue", "https://i.imgur.com/AnaMjsH.png") + .queue(channel, message -> { + message.addReaction("\u2B05").queue(); + message.addReaction("\u27A1").queue(); + }); break; case "restart": audioTrack = player.getPlayingTrack(); @@ -265,6 +273,10 @@ public class MusicCommand extends Command { try { channel.getGuild().getAudioManager().openAudioConnection(voiceChannel); MessageFactory.create("Entering Voice Channel: " + voiceChannel.getName()).setColor(member.getColor()).queue(channel); + if (voiceChannel.getGuild().getAudioManager().getSendingHandler() == null) { + voiceChannel.getGuild().getAudioManager().setSendingHandler + (getMusicManager(GuildManager.getInstance().getGuild(voiceChannel.getGuild())).getSendHandler()); + } } 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); 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 index 709e804..6ec39e5 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/general/QuoteCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/general/QuoteCommand.java @@ -20,13 +20,10 @@ public class QuoteCommand extends Command { @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()); + MessageFactory.create(quote[0]).setTitle("Author: " + quote[1]).footer("Requested by: " + member.getEffectiveName(), + member.getUser().getEffectiveAvatarUrl()).setTimestamp() + .setColor(member.getColor()).queue(channel); } private String[] getAdvice() { diff --git a/src/main/java/io/rixa/bot/commands/cmds/general/RankCommand.java b/src/main/java/io/rixa/bot/commands/cmds/general/RankCommand.java new file mode 100644 index 0000000..7cade8b --- /dev/null +++ b/src/main/java/io/rixa/bot/commands/cmds/general/RankCommand.java @@ -0,0 +1,85 @@ +package io.rixa.bot.commands.cmds.general; + +import io.rixa.bot.Rixa; +import io.rixa.bot.commands.Command; +import io.rixa.bot.commands.perms.RixaPermission; +import io.rixa.bot.data.storage.DatabaseAdapter; +import io.rixa.bot.guild.RixaGuild; +import io.rixa.bot.guild.manager.GuildManager; +import io.rixa.bot.guild.modules.module.LevelsModule; +import io.rixa.bot.pagination.ObjectPagination; +import io.rixa.bot.user.RixaUser; +import io.rixa.bot.user.manager.UserManager; +import io.rixa.bot.utils.DiscordUtils; +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 net.dv8tion.jda.core.entities.User; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collections; +import java.util.List; + +public class RankCommand extends Command { + + public RankCommand(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); + if (!rixaGuild.getModule("Levels").isEnabled()) { + MessageFactory.create("Levels are not enabled on this server!") + .setColor(member.getColor()).queue(channel); + return; + } + if (args.length == 0) { + getInfo(rixaGuild, member).queue(channel); + return; + } + List members = DiscordUtils.memberSearch(guild, String.join(" ", args), false); + if (members.isEmpty()) { + MessageFactory.create("Could not find valid member! Please try again!").setColor(member.getColor()).queue(channel); + return; + } + getInfo(rixaGuild, members.get(0)).queue(channel); + } + + private MessageFactory getInfo(RixaGuild rixaGuild, Member member) { + User author = member.getUser(); + int rank = 1; + int count = DatabaseAdapter.getInstance().get().queryForObject + ("SELECT COUNT(*) FROM `levels`", Integer.class); + if (count > 0) { + rank = DatabaseAdapter.getInstance().get().queryForObject("SELECT * FROM `levels` WHERE `guild_id` = ? ORDER BY `experience` DESC", + new Object[]{member.getGuild().getId()}, (resultSet, i) -> { + int main = 1; + + while (resultSet.next()) { + if (resultSet.getString("user_id").equalsIgnoreCase(member.getUser().getId())) { + return main; + } + main++; + } + return main; + }); + } + RixaUser rixaUser = UserManager.getInstance().getUser(member.getUser()); + int levels = rixaUser.getLevels(rixaGuild.getGuild().getId()); + return MessageFactory.create() + .setAuthor(author.getName(), author.getEffectiveAvatarUrl(), author.getEffectiveAvatarUrl()) + .setTitle(author.getName() + "'s level") + .setColor(member.getColor()) + .addField("Rank", String.valueOf(rank), true) + .addField("Level", String.valueOf(DiscordUtils.getLevelFromExperience(rixaUser.getLevels + (rixaGuild.getId()))), true) + .addField("Exp Needed", + DiscordUtils.getRemainingExperience(levels) + "/" + DiscordUtils.getNeededXP + (DiscordUtils.getLevelFromExperience(levels)).intValue(), false) + .addField("Total Exp", String.valueOf(levels), true); + } +} 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 index 45e22fc..c0bdf34 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/general/RoleMemberList.java +++ b/src/main/java/io/rixa/bot/commands/cmds/general/RoleMemberList.java @@ -31,11 +31,11 @@ public class RoleMemberList extends Command { 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); + MessageFactory.create(String.join(", ", membersWithRole)) + .setAuthor("Users with role: " + role.getName(), guild.getIconUrl()).setTimestamp() + .setColor(member.getColor()).queue(channel); } private String format(Member member) { 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 index c923f31..a604651 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/moderator/ClearCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/moderator/ClearCommand.java @@ -17,6 +17,7 @@ import net.dv8tion.jda.core.exceptions.PermissionException; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class ClearCommand extends Command { @@ -35,18 +36,14 @@ public class ClearCommand extends Command { 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()) + MessageFactory.create(((i == 0) ? "Could not find any messages to delete" : "Successfully deleted *" + i + + "* messages in " + channel.getAsMention())) .footer("Requested by: " + member.getEffectiveName(), member.getUser().getEffectiveAvatarUrl()) .setColor(member.getColor()) .queue(channel); @@ -55,17 +52,17 @@ public class ClearCommand extends Command { 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 -> { + List newMessages = new ArrayList<>(messageHistory.stream().filter(message -> !pinnedMessages.contains(message)).collect(Collectors.toList())); + /*messageHistory.forEach(message -> { if (!(pinnedMessages.contains(message))) { newMessages.add(message); } - }); + });*/ // !mute Savvy 10s Hello Savvy! try { + i = newMessages.size(); 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); 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 index fc6f44b..e365181 100644 --- a/src/main/java/io/rixa/bot/commands/cmds/moderator/MuteCommand.java +++ b/src/main/java/io/rixa/bot/commands/cmds/moderator/MuteCommand.java @@ -24,6 +24,7 @@ public class MuteCommand extends Command { Object[] objArray = DiscordUtils.memberSearchArray(guild, argumentString, false); if (objArray.length == 0) { MessageFactory.create("Could not find member!").setColor(member.getColor()).queue(channel); + return; } Member targetMember = (Member) objArray[1]; String targetMemberName = String.valueOf(objArray[0]); @@ -33,9 +34,14 @@ public class MuteCommand extends Command { } argumentString = argumentString.replaceFirst(targetMemberName, "").trim(); args = argumentString.split(" "); + if (args[0].length() == 0) { + // Incorrect Usage + return; + } 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); + MessageFactory.create("Duration: " + time + "\nReason: " + argumentString + "\nDuration in Milliseconds: " + milliseconds) + .queue(channel); } } diff --git a/src/main/java/io/rixa/bot/commands/perms/RixaPermission.java b/src/main/java/io/rixa/bot/commands/perms/RixaPermission.java index b00b2ea..b997034 100644 --- a/src/main/java/io/rixa/bot/commands/perms/RixaPermission.java +++ b/src/main/java/io/rixa/bot/commands/perms/RixaPermission.java @@ -11,7 +11,6 @@ public enum RixaPermission { KICK_MEMBER, BAN_MEMBER, BATCH_MOVE, - UNMUTE, TOGGLE_RAIDMODE; public static RixaPermission fromString(String string) { diff --git a/src/main/java/io/rixa/bot/data/storage/DatabaseAdapter.java b/src/main/java/io/rixa/bot/data/storage/DatabaseAdapter.java index 5e7d3c3..61add11 100644 --- a/src/main/java/io/rixa/bot/data/storage/DatabaseAdapter.java +++ b/src/main/java/io/rixa/bot/data/storage/DatabaseAdapter.java @@ -2,6 +2,7 @@ package io.rixa.bot.data.storage; import io.rixa.bot.Rixa; import io.rixa.bot.data.config.Configuration; +import io.rixa.bot.data.storage.enums.DatabaseTables; import io.rixa.bot.data.storage.enums.Statements; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; @@ -14,6 +15,7 @@ import org.springframework.jdbc.datasource.DriverManagerDataSource; import java.sql.Array; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Arrays; import java.util.List; public class DatabaseAdapter { @@ -35,7 +37,6 @@ public class DatabaseAdapter { dataSource.setDriverClassName("com.mysql.jdbc.Driver"); String url = String.format("jdbc:mysql://%s:%s/%s", config.getSqlCredentials().get("hostName"), config.getSqlCredentials().get("port"), config.getSqlCredentials().get("databaseName")); - System.out.println(url); dataSource.setUrl(url); dataSource.setUsername(config.getSqlCredentials().get("userName")); dataSource.setPassword(config.getSqlCredentials().get("password")); diff --git a/src/main/java/io/rixa/bot/data/storage/enums/DatabaseTables.java b/src/main/java/io/rixa/bot/data/storage/enums/DatabaseTables.java new file mode 100644 index 0000000..201ecf3 --- /dev/null +++ b/src/main/java/io/rixa/bot/data/storage/enums/DatabaseTables.java @@ -0,0 +1,58 @@ +package io.rixa.bot.data.storage.enums; + +public enum DatabaseTables { + + CORE("CREATE TABLE IF NOT EXISTS `core` ( `guild_id` varchar(255) NOT NULL PRIMARY KEY, `guild_name` varchar(255) NOT NULL," + + " `description` text, `enlisted` tinyint(1) NOT NULL DEFAULT '0', `icon` varchar(255) DEFAULT NULL, `link` varchar(255) DEFAULT NULL," + + " `keywords` text, `creation_date` varchar(255) NOT NULL DEFAULT 'N/A', `guild_region` varchar(255) NOT NULL DEFAULT 'N/A'," + + " `guild_owner` varchar(255) NOT NULL DEFAULT 'N/A'\n" + + ");"), + + LEVELS("CREATE TABLE IF NOT EXISTS `levels` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `guild_id` varchar(255) NOT NULL, `user_id` varchar(255) NOT NULL," + + " `experience` int(90) NOT NULL\n" + + ");"), + + MODULES("CREATE TABLE IF NOT EXISTS `modules` (`guild_id` varchar(255) DEFAULT NULL, `levels` tinyint(1) NOT NULL DEFAULT '1', `conversation` tinyint(1) NOT NULL DEFAULT '1');"), + + MUSIC("CREATE TABLE IF NOT EXISTS `music` ( `guild_id` varchar(255) NOT NULL UNIQUE PRIMARY KEY, `music_role` varchar(255) NOT NULL DEFAULT 'default_value'," + + " `skip_amount` int(5) NOT NULL DEFAULT '0', `max_playlist_amount` int(5) NOT NULL DEFAULT '100', `enabled` tinyint(1) NOT NULL DEFAULT '0'\n" + + ");"), + + PERMISSIONS("CREATE TABLE IF NOT EXISTS `permissions` ( `role_id` varchar(255) NOT NULL, `guild_id` varchar(255) NOT NULL, `MUTE` tinyint(1) NOT NULL DEFAULT '0'," + + " `ADD_ROLE` tinyint(1) NOT NULL DEFAULT '0', `REMOVE_ROLE` tinyint(1) NOT NULL DEFAULT '0', `CLEAR_CHAT` tinyint(1) NOT NULL DEFAULT '0'," + + " `ACCESS_CONFIG` tinyint(1) NOT NULL DEFAULT '0', `PM_MESSAGE` tinyint(1) NOT NULL DEFAULT '0', `KICK_MEMBER` tinyint(1) NOT NULL DEFAULT '0'," + + " `BAN_MEMBER` tinyint(1) NOT NULL DEFAULT '0', `TOGGLE_RAIDMODE` tinyint(4) NOT NULL DEFAULT '0', `UNMUTE` tinyint(1) NOT NULL DEFAULT '0');"), + + POLLS("CREATE TABLE IF NOT EXISTS `polls` ( `id` int(9) NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` varchar(255) NOT NULL, `description` text," + + " `option_1` varchar(255) DEFAULT NULL, `option_2` varchar(255) DEFAULT NULL, `option_3` varchar(255) DEFAULT NULL," + + " `option_4` varchar(255) DEFAULT NULL, `option_5` varchar(255) DEFAULT NULL, `option_6` varchar(255) DEFAULT NULL," + + " `option_7` varchar(255) DEFAULT NULL, `option_8` varchar(255) DEFAULT NULL, `option_9` varchar(255) DEFAULT NULL," + + " `option_10` varchar(255) DEFAULT NULL);"), + + ROLE_REWARDS("CREATE TABLE IF NOT EXISTS `role_rewards` ( `guild_id` varchar(255) NOT NULL PRIMARY KEY, `level` int(9) NOT NULL, `role_id` varchar(255) NOT NULL\n" + + ");"), + + SETTINGS("CREATE TABLE IF NOT EXISTS `settings` ( `guild_id` varchar(255) NOT NULL, `log_enabled` tinyint(1) NOT NULL, `log_channel` varchar(255) NOT NULL," + + " `joinMessage` text NOT NULL, `quitMessage` text NOT NULL, `greetings` varchar(255) NOT NULL, `farewell` varchar(255) NOT NULL," + + " `prefix` varchar(5) NOT NULL, `joinPm` text NOT NULL, `joinVerification` tinyint(1) NOT NULL, `defaultRole` varchar(255) NOT NULL, `muteRole` varchar(255) NOT NULL\n" + + ")"), + + TWITTER("CREATE TABLE IF NOT EXISTS `twitter` (`guild_id` varchar(255) NOT NULL, `consumer_key` varchar(255) NOT NULL, `consumer_secret` varchar(255) NOT NULL, " + + "`access_key` varchar(255) NOT NULL, `access_secret` varchar(255) NOT NULL, `tweet_channel` varchar(255) NOT NULL, `updates_channel` varchar(255) NOT NULL)"), + + USER("CREATE TABLE IF NOT EXISTS `user` (`user_id` varchar(255) NOT NULL UNIQUE, `user_name` varchar(255) NOT NULL, `avatar_hash` varchar(255) DEFAULT 'N/A');"); // USER is mostly used for http://rixa.io. + + private String query; + + DatabaseTables(String s) { + query = s; + } + + public String toString() { + return this.name(); + } + + public String getQuery() { + return this.query; + } +} diff --git a/src/main/java/io/rixa/bot/events/MessageListener.java b/src/main/java/io/rixa/bot/events/MessageListener.java index 59b8382..cd1f3a0 100644 --- a/src/main/java/io/rixa/bot/events/MessageListener.java +++ b/src/main/java/io/rixa/bot/events/MessageListener.java @@ -3,52 +3,86 @@ package io.rixa.bot.events; import io.rixa.bot.Rixa; import io.rixa.bot.commands.Command; import io.rixa.bot.commands.exceptions.CommandNotFoundException; +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.ConversationModule; +import io.rixa.bot.user.RixaUser; +import io.rixa.bot.user.manager.UserManager; +import io.rixa.bot.utils.DiscordUtils; import io.rixa.bot.utils.MessageFactory; +import java.io.IOException; +import java.util.concurrent.TimeUnit; import net.dv8tion.jda.core.entities.TextChannel; -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) { - String message = event.getMessage().getContent().trim(); - RixaGuild rixaGuild = GuildManager.getInstance().getGuild(event.getGuild()); - if (message.startsWith("@" + event.getGuild().getSelfMember().getEffectiveName())) { - chatter(rixaGuild, event.getChannel(), message.replace("@" + event.getGuild().getSelfMember().getEffectiveName(), "")); - return; - } - String prefix = "!"; - if (!(message.startsWith(prefix))) return; - 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); + @SubscribeEvent + public void onMessage(GuildMessageReceivedEvent event) { + if (event.getAuthor().isBot()) { + return; } + String message = event.getMessage().getContentRaw().trim(); + RixaGuild rixaGuild = GuildManager.getInstance().getGuild(event.getGuild()); + if (message.startsWith("@" + event.getGuild().getSelfMember().getEffectiveName())) { + chatter(rixaGuild, event.getChannel(), + message.replace("@" + event.getGuild().getSelfMember().getEffectiveName(), "")); + return; + } + String prefix = rixaGuild.getSettings().getPrefix(); + if (message.startsWith(prefix)) { + 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); + return; + } + RixaUser rixaUser = UserManager.getInstance().getUser(event.getAuthor()); + if (rixaUser.awardIfCan(event.getGuild())) { + int level = DiscordUtils.getLevelFromExperience(rixaUser.getLevels(rixaGuild.getId())); + MessageFactory + .create(event.getAuthor().getAsMention() + " has leveled up to **level " + level + "**!") + .setTimestamp() + .setColor(event.getMember().getColor()) + .setAuthor("Leveled Up!", null, event.getAuthor().getAvatarUrl()) + .footer("Rixa Levels", event.getJDA().getSelfUser().getAvatarUrl()) + .queue(event.getChannel()); + } + } - 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); - event.getMessage().delete().queue(); - command.execute(commandName, event.getGuild(), event.getMember(), event.getChannel(), args); - } catch (CommandNotFoundException | IOException ignored) { } + 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); + event.getMessage().delete().queueAfter(3, TimeUnit.SECONDS); + RixaGuild rixaGuild = GuildManager.getInstance().getGuild(event.getGuild()); + if (command.getPermission() != null && command.getPermission() != RixaPermission.NONE && + (!rixaGuild.hasPermission(event.getMember().getUser(), command.getPermission())) + && (!Rixa.getInstance().getConfiguration().isBotAdmin(event.getAuthor().getId()))) { + MessageFactory.create("Sorry! You do not have permission for this command!") + .setColor(event.getMember().getColor()).queue(event.getChannel()); + return; + } + command.execute(commandName, event.getGuild(), event.getMember(), event.getChannel(), args); + } catch (CommandNotFoundException | IOException ignored) { } + } - private void chatter(RixaGuild rixaGuild, TextChannel channel, String message) { - ConversationModule conversationModule = (ConversationModule) rixaGuild.getModule("Conversation"); - if (!conversationModule.isEnabled()) return; - try { - MessageFactory.create(conversationModule.getChatBotSession().think(message)).selfDestruct(0) - .queue(channel); - } catch (Exception ignored) {} + private void chatter(RixaGuild rixaGuild, TextChannel channel, String message) { + ConversationModule conversationModule = (ConversationModule) rixaGuild + .getModule("Conversation"); + if (!conversationModule.isEnabled()) { + return; } + try { + MessageFactory.create(conversationModule.getChatBotSession().think(message)).selfDestruct(0) + .queue(channel); + } catch (Exception ignored) { + } + } } diff --git a/src/main/java/io/rixa/bot/events/ReadyListener.java b/src/main/java/io/rixa/bot/events/ReadyListener.java index af3c21c..e75b81c 100644 --- a/src/main/java/io/rixa/bot/events/ReadyListener.java +++ b/src/main/java/io/rixa/bot/events/ReadyListener.java @@ -1,17 +1,31 @@ package io.rixa.bot.events; import io.rixa.bot.guild.manager.GuildManager; +import io.rixa.bot.user.RixaUser; +import io.rixa.bot.user.manager.UserManager; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import net.dv8tion.jda.core.events.ReadyEvent; import net.dv8tion.jda.core.hooks.SubscribeEvent; public class ReadyListener { - @SubscribeEvent - public void onReady(ReadyEvent event) { - if (event.getJDA().getGuilds().size() == 0) return; - System.out.println("Ready Event Triggered"); - event.getJDA().getGuilds().forEach(guild -> { - GuildManager.getInstance().addGuild(guild); - }); + private ScheduledExecutorService scheduler; + + public ReadyListener() { + this.scheduler = Executors.newSingleThreadScheduledExecutor(); + } + + @SubscribeEvent + public void onReady(ReadyEvent event) { + if (event.getJDA().getGuilds().size() == 0) { + return; } + this.scheduler.scheduleWithFixedDelay(() -> { + event.getJDA().getGuilds().forEach(guild -> + GuildManager.getInstance().addGuild(guild).getModule("Levels").reload()); + UserManager.getInstance().getUserMap().values().forEach(RixaUser::save); + }, 0, 5, TimeUnit.MINUTES); + } } diff --git a/src/main/java/io/rixa/bot/events/UserListener.java b/src/main/java/io/rixa/bot/events/UserListener.java index 7c5fb63..ad57b7b 100644 --- a/src/main/java/io/rixa/bot/events/UserListener.java +++ b/src/main/java/io/rixa/bot/events/UserListener.java @@ -8,78 +8,90 @@ 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 onJoin(GuildMemberJoinEvent event) { + RixaGuild rixaGuild = GuildManager.getInstance().getGuild(event.getGuild()); + if (!rixaGuild.getSettings().getJoinMessage().equalsIgnoreCase("default_value") + && rixaGuild.getSettings().getGreetings() != null) { + 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).queue(rixaGuild.getSettings().getGreetings()); } + 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).send(event.getUser(), success -> + success.addReaction("\uD83D\uDC4D").queue(s -> + success.addReaction("\uD83D\uDC4E").queue())); + } // 👍 - @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 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("\uD83D\uDC4D") && + !event.getReaction().getReactionEmote().getName().contains("\uD83D\uDC4E")) { + 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()); - } + @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") && + rixaGuild.getSettings().getFarewell() != null) { + 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).queue(rixaGuild.getSettings().getFarewell()); + } + } } diff --git a/src/main/java/io/rixa/bot/guild/RixaGuild.java b/src/main/java/io/rixa/bot/guild/RixaGuild.java index e39009a..c566c78 100644 --- a/src/main/java/io/rixa/bot/guild/RixaGuild.java +++ b/src/main/java/io/rixa/bot/guild/RixaGuild.java @@ -1,18 +1,22 @@ package io.rixa.bot.guild; +import io.rixa.bot.commands.perms.RixaPermission; +import io.rixa.bot.data.storage.DatabaseAdapter; 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.LevelsModule; import io.rixa.bot.guild.modules.module.MusicModule; import io.rixa.bot.guild.settings.Settings; +import io.rixa.bot.user.manager.UserManager; 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.User; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; public class RixaGuild implements IGuild { @@ -20,6 +24,7 @@ public class RixaGuild implements IGuild { @Getter private List confirmationUsers; @Getter @Setter private List keywords; @Getter @Setter private String description; + @Getter private Map> permissionMap; @Getter private final String id; @Getter private Guild guild; @Getter private Settings settings; @@ -30,24 +35,46 @@ public class RixaGuild implements IGuild { modules = new HashMap<>(); keywords = new ArrayList<>(); confirmationUsers = new ArrayList<>(); + permissionMap = new HashMap<>(); load(); } @Override public void load() { - registerModules( - new ConversationModule("Conversation", "Have a conversation with Rixa!", this), - new MusicModule("Music", "Listen to music from within discord!", this) - ); settings = new Settings(this); + if (!(DatabaseAdapter.getInstance().exists("modules", "guild_id", guild.getId()))) { + DatabaseAdapter.getInstance().get().update + ("INSERT INTO `modules` (`guild_id`, `levels`, `conversation`) VALUES (?, ?, ?);", + guild.getId(), false, true); + } + registerModules( + new ConversationModule("conversation", "Have a conversation with Rixa!", this), + new MusicModule("music", "Listen to music from within discord!", this), + new LevelsModule("levels", "Levels for your discord server", this) + ); } @Override - public void save() { } + public void save() { + modules.values().forEach(RixaModule::save); + settings.save(); + + permissionMap.keySet().forEach(object -> { + List permissions = permissionMap.get(object); + List permission = new ArrayList<>(); + Arrays.stream(RixaPermission.values()).forEach(stringPermission -> + permission.add("`" + stringPermission.toString() + "`=" + + (permissions.contains(stringPermission) ? "'1'" : "'0'"))); + DatabaseAdapter.getInstance().get().update( + "UPDATE `permissions` SET " + String.join(", " + permission) + + " WHERE `guild_id` = ? AND `object_id` = ?", + guild.getId(), object); + }); + } @Override public RixaModule getModule(String id) { - return modules.get(id); + return modules.get(id.toLowerCase()); } private void registerModules(RixaModule... modules) { @@ -55,6 +82,8 @@ public class RixaGuild implements IGuild { registerModule(module); } } + + @Override public RixaModule registerModule(RixaModule module) { if (!(isRegistered(module.getName()))) modules.put(module.getName(), module); @@ -63,6 +92,40 @@ public class RixaGuild implements IGuild { @Override public boolean isRegistered(String id) { - return modules.containsKey(id); + return modules.containsKey(id.toLowerCase()); + } + + @Override + public boolean hasPermission(User user, RixaPermission permission) { + Member member = guild.getMember(user); + if (member == null) return false; + if (!member.getRoles().stream().filter(role -> (permissionMap.containsKey(role.getId()) && + permissionMap.get(role.getId()).contains(permission))) + .collect(Collectors.toList()).isEmpty()) { + return true; + } + return UserManager.getInstance().getUser + (user).hasPermission(guild.getId(), permission); + } + + @Override + public void addPermission(String roleId, RixaPermission rixaPermission) { + if (!permissionMap.containsKey(roleId)) { + permissionMap.put(roleId, Collections.singletonList(rixaPermission)); + return; + } + List permissionsList = permissionMap.get(roleId); + if (permissionsList.contains(rixaPermission)) return; + permissionsList.add(rixaPermission); + permissionMap.replace(roleId, permissionsList); + } + + @Override + public void removePermission(String roleId, RixaPermission rixaPermission) { + if (!permissionMap.containsKey(roleId)) return; + List permissionsList = permissionMap.get(roleId); + if (!permissionsList.contains(rixaPermission)) return; + permissionsList.remove(rixaPermission); + permissionMap.replace(roleId, permissionsList); } } diff --git a/src/main/java/io/rixa/bot/guild/enums/PermissionType.java b/src/main/java/io/rixa/bot/guild/enums/PermissionType.java new file mode 100644 index 0000000..c0d9662 --- /dev/null +++ b/src/main/java/io/rixa/bot/guild/enums/PermissionType.java @@ -0,0 +1,7 @@ +package io.rixa.bot.guild.enums; + +public enum PermissionType { + + USER, + GUILD +} 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 fea62a2..c45392d 100644 --- a/src/main/java/io/rixa/bot/guild/manager/GuildManager.java +++ b/src/main/java/io/rixa/bot/guild/manager/GuildManager.java @@ -38,6 +38,7 @@ public class GuildManager { } public RixaGuild addGuild(Guild guild) { + if (hasGuild(guild.getId())) return rixaGuildMap.get(guild.getId()); if (!(DatabaseAdapter.getInstance().exists("core", "guild_id", guild.getId()))) { insert(guild); } diff --git a/src/main/java/io/rixa/bot/guild/manager/IGuild.java b/src/main/java/io/rixa/bot/guild/manager/IGuild.java index 351766c..f4322ec 100644 --- a/src/main/java/io/rixa/bot/guild/manager/IGuild.java +++ b/src/main/java/io/rixa/bot/guild/manager/IGuild.java @@ -1,6 +1,8 @@ package io.rixa.bot.guild.manager; +import io.rixa.bot.commands.perms.RixaPermission; import io.rixa.bot.guild.modules.RixaModule; +import net.dv8tion.jda.core.entities.User; import java.util.List; @@ -14,4 +16,9 @@ public interface IGuild { boolean isRegistered(String id); void setDescription(String description); void setKeywords(List keywords); + + boolean hasPermission(User user, RixaPermission permission); + + void addPermission(String guildId, RixaPermission permission); + void removePermission(String guildId, RixaPermission rixaPermission); } 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 9d05159..ffcf8c0 100644 --- a/src/main/java/io/rixa/bot/guild/modules/RixaModule.java +++ b/src/main/java/io/rixa/bot/guild/modules/RixaModule.java @@ -1,6 +1,5 @@ package io.rixa.bot.guild.modules; -import io.rixa.bot.Rixa; import io.rixa.bot.guild.RixaGuild; public interface RixaModule { @@ -8,6 +7,7 @@ public interface RixaModule { String getName(); String getDescription(); boolean isEnabled(); + void setEnabled(boolean b); void load(); void save(); void reload(); 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 bb0da1c..60140c9 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 @@ -25,19 +25,21 @@ public class ConversationModule implements RixaModule { this.description = description; this.enabled = true; this.guild = guild; + load(); } @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"))); + new Object[]{guild.getId()}, (resultSet, i) -> resultSet.getBoolean(getName()))); reload(); } @Override public void save() { // Check & Set if enabled; + DatabaseAdapter.getInstance().get().update("UPDATE `modules` SET `" + name + "` = ? WHERE `guild_id` = ?;", enabled, guild.getId()); } @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 31d2d15..c6db57c 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,34 +1,76 @@ package io.rixa.bot.guild.modules.module; +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 io.rixa.bot.pagination.ObjectPagination; +import io.rixa.bot.user.RixaUser; +import io.rixa.bot.user.manager.UserManager; import lombok.Getter; import lombok.Setter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + public class LevelsModule implements RixaModule { - @Getter private String name, description; - @Getter @Setter boolean enabled; - @Getter private RixaGuild guild; + @Getter + private String name, description; + @Getter + @Setter + boolean enabled; + @Getter + private RixaGuild guild; + @Getter + private ObjectPagination objectPagination; public LevelsModule(String name, String description, RixaGuild rixaGuild) { this.name = name; this.description = description; this.guild = rixaGuild; + load(); } @Override public void load() { - + // SELECT * FROM `levels` ORDER BY `experience` DESC LIMIT 100, 50; + setEnabled(DatabaseAdapter.getInstance().get().queryForObject + (Statements.SELECT_MODULE_STATUS.getStatement("{module_name}", getName()), + new Object[]{guild.getId()}, (resultSet, i) -> resultSet.getBoolean(getName()))); + reload(); } @Override public void save() { - + DatabaseAdapter.getInstance().get().update("UPDATE `modules` SET `" + name + "` = ? WHERE `guild_id` = ?;", enabled, guild.getId()); } @Override public void reload() { - + if (!isEnabled()) return; + UserManager.getInstance().getUserMap().values().forEach(RixaUser::save); + int count = DatabaseAdapter.getInstance().get().queryForObject + ("SELECT COUNT(*) FROM `levels`", Integer.class); + if (count == 0) { + objectPagination = new ObjectPagination(Collections.emptyList(), 10); + return; + } + List expList = DatabaseAdapter.getInstance().get().queryForObject + (Statements.SELECT_ALL_FROM_TABLE.getStatement("{table_name}", "levels"), + new Object[]{guild.getId()}, (resultSet, i) -> { + List list = new ArrayList<>(); + resultSet.beforeFirst(); + while (resultSet.next()) { + list.add(resultSet.getString("user_id") + ":" + + resultSet.getInt("experience")); + } + return list; + }); + if (objectPagination == null) + objectPagination = new ObjectPagination(expList, 10); + else + objectPagination.updateList(expList); } -} +} \ No newline at end of file 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 index c3f8032..1bb67bf 100644 --- a/src/main/java/io/rixa/bot/guild/modules/module/MusicModule.java +++ b/src/main/java/io/rixa/bot/guild/modules/module/MusicModule.java @@ -11,6 +11,8 @@ import lombok.Getter; import lombok.Setter; import net.dv8tion.jda.core.entities.Role; +import java.util.concurrent.ExecutorService; + public class MusicModule implements RixaModule { @Getter private String name, description; @@ -24,32 +26,44 @@ public class MusicModule implements RixaModule { this.description = description; this.enabled = true; this.guild = guild; + load(); } @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"))); + if (!(DatabaseAdapter.getInstance().exists("music", "guild_id", guild.getId()))) { + insert(); + this.enabled = false; + return; + } + setEnabled(DatabaseAdapter.getInstance().get().queryForObject("SELECT `enabled` FROM `music` WHERE `guild_id` = ?", + new Object[]{guild.getId()}, (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 `enabled` = ? WHERE `guild_id` = ?", enabled, guild.getId()); + if (musicRole != null) 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"), + DatabaseAdapter.getInstance().get().queryForObject(Statements.SELECT_ALL_FROM_TABLE.getStatement("{table_name}", "music"), new Object[] { guild.getId() }, (resultSet, i) -> { - if (guild.getGuild().getRoleById(resultSet.getString("music_role")) != null) { + if (!resultSet.getString("music_role").equalsIgnoreCase("default_value") + && guild.getGuild().getRoleById(resultSet.getString("music_role")) != null) { this.musicRole = guild.getGuild().getRoleById(resultSet.getString("music_role")); } return 0; }); } + + private void insert() { + DatabaseAdapter.getInstance().get().update("INSERT INTO `music` (`guild_id`, `music_role`, `enabled`) VALUES (?, ?, ?);", + guild.getId(), "default_value", false); + } } 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 index c53cf1b..ae82730 100644 --- 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 @@ -4,8 +4,7 @@ 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 io.rixa.bot.pagination.Pagination; import lombok.Getter; import lombok.Setter; @@ -19,7 +18,7 @@ public class TrackScheduler extends AudioEventAdapter { @Getter private final AudioPlayer player; @Getter private final Queue queue; @Getter private AudioTrack lastTrack; - @Getter private QueuePagination queuePagination; + @Getter private Pagination queuePagination; /** * @param player The audio player this scheduler uses @@ -27,7 +26,7 @@ public class TrackScheduler extends AudioEventAdapter { public TrackScheduler(AudioPlayer player) { this.player = player; this.queue = new LinkedList<>(); - queuePagination = new QueuePagination(queue, 5); + queuePagination = new Pagination(queue, 5); } /** diff --git a/src/main/java/io/rixa/bot/guild/settings/Settings.java b/src/main/java/io/rixa/bot/guild/settings/Settings.java index 82acc70..0127a36 100644 --- a/src/main/java/io/rixa/bot/guild/settings/Settings.java +++ b/src/main/java/io/rixa/bot/guild/settings/Settings.java @@ -22,15 +22,24 @@ public class Settings implements RixaSettings { public Settings(RixaGuild rixaGuild) { this.rixaGuild = rixaGuild; + load(); } @Override public void load() { + if (!(DatabaseAdapter.getInstance().exists("settings", "guild_id", rixaGuild.getId()))) { + DatabaseAdapter.getInstance().get().update + ("INSERT INTO settings(guild_id, log_enabled, log_channel, joinMessage, quitMessage, greetings, farewell," + + " prefix, joinPm, joinVerification, defaultRole, muteRole) VALUES " + + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + rixaGuild.getId(), false, "default_value", "default_value", "default_value", "default_value", + "default_value", "!", "default", 0, "default_value", "default_value"); + } 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")); + setQuitMessage(resultSet.getString("quitMessage")); setJoinPrivateMessage(resultSet.getString("joinPm")); setJoinVerification(resultSet.getBoolean("joinVerification")); String greetingsId = resultSet.getString("greetings"); @@ -55,6 +64,14 @@ public class Settings implements RixaSettings { @Override public void save() { - + DatabaseAdapter.getInstance().get().update("UPDATE `settings` SET " + + "`prefix` = ?, `joinMessage` = ?, `quitMessage` = ?, " + + "`joinPm` = ?, `joinVerification` = ?, `greetings` = ?, " + + "`farewell` = ?, `defaultRole` = ?, `muteRole` = ?;", + prefix, joinMessage, quitMessage, joinPrivateMessage, joinVerification, + ((greetings == null) ? "default_value" : greetings.getId()), + ((farewell == null) ? "default_value" : farewell.getId()), + ((defaultRole == null) ? "default_value" : defaultRole.getId()), + ((muteRole == null) ? "default_value" : muteRole.getId())); } -} +} \ No newline at end of file diff --git a/src/main/java/io/rixa/bot/pagination/Pagination.java b/src/main/java/io/rixa/bot/pagination/Pagination.java new file mode 100644 index 0000000..c0d0014 --- /dev/null +++ b/src/main/java/io/rixa/bot/pagination/Pagination.java @@ -0,0 +1,42 @@ +package io.rixa.bot.pagination; + +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class Pagination { + + @Getter @Setter private List objects; + @Getter private int maxPage, pageSize; + + public Pagination(Collection objects, int pageSize) { + this.objects = new ArrayList<>(objects); + this.pageSize = pageSize; + this.maxPage = (objects.size() / pageSize + (objects.size() % pageSize)); + } + + public List getPage(int page) { + if(objects.isEmpty()) { + return Collections.emptyList(); + } + if(pageSize <= 0 || page <= 0) { + throw new IllegalArgumentException("Invalid page size: " + pageSize); + } + + int fromIndex = (page - 1) * pageSize; + if(objects.size() < fromIndex){ + return Collections.emptyList(); + } + // toIndex exclusive + return objects.subList(fromIndex, Math.min(fromIndex + pageSize, objects.size())); + } + + public void updateList(Collection objects) { + this.objects.clear(); + this.objects.addAll(objects); + } +} diff --git a/src/main/java/io/rixa/bot/pagination/QueuePagination.java b/src/main/java/io/rixa/bot/pagination/QueuePagination.java deleted file mode 100644 index 675c5dd..0000000 --- a/src/main/java/io/rixa/bot/pagination/QueuePagination.java +++ /dev/null @@ -1,46 +0,0 @@ -package io.rixa.bot.pagination; - -import com.sedmelluq.discord.lavaplayer.track.AudioTrack; -import lombok.Getter; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; - -public class QueuePagination { - - @Getter private Queue objects; - @Getter List listObjects; - @Getter private int maxPage, pageSize; - public QueuePagination(Queue objects, int pageSize) { - this.objects = objects; - this.pageSize = pageSize; - this.maxPage = (objects.size() / pageSize + (objects.size() % pageSize)); - } - - public List getPage(int page) { - if(listObjects.isEmpty()) { - return Collections.emptyList(); - } - if(pageSize <= 0 || page <= 0) { - throw new IllegalArgumentException("Invalid page size: " + pageSize); - } - - int fromIndex = (page - 1) * pageSize; - if(objects.size() < fromIndex){ - return Collections.emptyList(); - } - // toIndex exclusive - return listObjects.subList(fromIndex, Math.min(fromIndex + pageSize, objects.size())); - } - - public List asList() { - return listObjects; - } - - public void updateList(Queue obj) { - this.objects = obj; - this.listObjects = new LinkedList<>(getObjects()); - } -} diff --git a/src/main/java/io/rixa/bot/user/RixaUser.java b/src/main/java/io/rixa/bot/user/RixaUser.java index 15ea926..18d5b84 100644 --- a/src/main/java/io/rixa/bot/user/RixaUser.java +++ b/src/main/java/io/rixa/bot/user/RixaUser.java @@ -1,9 +1,119 @@ package io.rixa.bot.user; import io.rixa.bot.commands.perms.RixaPermission; +import io.rixa.bot.data.storage.DatabaseAdapter; +import io.rixa.bot.data.storage.enums.Statements; +import io.rixa.bot.guild.enums.PermissionType; +import io.rixa.bot.pagination.ObjectPagination; +import io.rixa.bot.user.mapper.UserPermissionsMapper; +import io.rixa.bot.utils.DiscordUtils; +import lombok.Getter; +import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.User; +import org.springframework.dao.EmptyResultDataAccessException; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; public class RixaUser { - public boolean hasPermission(RixaPermission rixaPermission) { - return true; + + @Getter + private User user; + @Getter + private Map levels; + @Getter + private Map> permissions; + @Getter + private long last_awarded; + + public RixaUser(User user) { + this.user = user; + levels = new HashMap<>(); + permissions = new HashMap<>(); + last_awarded = (System.currentTimeMillis() - 60000); + load(); + } + + private void load() { + int count = DatabaseAdapter.getInstance().get().queryForObject + ("SELECT COUNT(*) FROM `levels` WHERE `user_id` = ?", new Object[] { user.getId() }, Integer.class); + if (count > 0) { + DatabaseAdapter.getInstance().get().queryForObject("SELECT * FROM `levels` WHERE `user_id` = ?", + new Object[]{user.getId()}, + (resultSet, i) -> { + resultSet.beforeFirst(); + while (resultSet.next()) { + levels.put(resultSet.getString("guild_id"), resultSet.getInt("experience")); + } + return 0; + }); + } + permissions.clear(); + permissions.putAll(DatabaseAdapter.getInstance().get().query("SELECT * FROM `permissions` WHERE `type` = ? AND `object_id` = ?", + new Object[]{PermissionType.USER, user.getId()}, new UserPermissionsMapper())); + } + + public void save() { + levels.forEach((guildId, integer) -> { + int i = DatabaseAdapter.getInstance().get().queryForObject + ("SELECT COUNT(*) FROM `levels` WHERE `guild_id` = ? AND `user_id` = ?", new Object[]{ + guildId, user.getId() + }, Integer.class); + if (i > 0) { + DatabaseAdapter.getInstance().get().update( + "UPDATE `levels` SET `experience` = ? WHERE `guild_id` = ? AND `user_id` = ?", integer, guildId, + user.getId()); + return; + } + DatabaseAdapter.getInstance().get().update + ("INSERT INTO `levels` (guild_id, user_id, experience) VALUES (?, ?, ?);", guildId, user.getId(), integer); + }); + } + + public boolean awardIfCan(Guild guild) { + long b = ((System.currentTimeMillis() - last_awarded) / 1000); + if (b < 60) { + return false; + } + int amountAdding = ThreadLocalRandom.current().nextInt(15, 25); + int exp = levels.getOrDefault(guild.getId(), 0); + int currentLevel = DiscordUtils.getLevelFromExperience(exp); + if (levels.containsKey(guild.getId())) { + levels.replace(guild.getId(), exp + amountAdding); + } else { + levels.put(guild.getId(), exp + amountAdding); + } + this.last_awarded = System.currentTimeMillis(); + return currentLevel < DiscordUtils.getLevelFromExperience(levels.get(guild.getId())); + } + + public void addPermission(String guildId, RixaPermission rixaPermission) { + if (!permissions.containsKey(guildId)) { + permissions.put(guildId, Collections.singletonList(rixaPermission)); + return; + } + List permissionsList = permissions.get(guildId); + if (permissionsList.contains(rixaPermission)) return; + permissionsList.add(rixaPermission); + permissions.replace(guildId, permissionsList); + } + + public void removePermission(String guildId, RixaPermission rixaPermission) { + if (!permissions.containsKey(guildId)) return; + List permissionsList = permissions.get(guildId); + if (!permissionsList.contains(rixaPermission)) return; + permissionsList.remove(rixaPermission); + permissions.replace(guildId, permissionsList); + } + + public boolean hasPermission(String guildId, RixaPermission rixaPermission) { + return permissions.containsKey(guildId) && permissions.get(guildId).contains(rixaPermission); + } + + public int getLevels(String id) { + return levels.getOrDefault(id, 0); } } diff --git a/src/main/java/io/rixa/bot/user/manager/UserManager.java b/src/main/java/io/rixa/bot/user/manager/UserManager.java new file mode 100644 index 0000000..75328ee --- /dev/null +++ b/src/main/java/io/rixa/bot/user/manager/UserManager.java @@ -0,0 +1,42 @@ +package io.rixa.bot.user.manager; + +import io.rixa.bot.user.RixaUser; +import lombok.Getter; +import net.dv8tion.jda.core.entities.User; + +import java.util.HashMap; +import java.util.Map; + +public class UserManager { + + private static UserManager instance; + @Getter private Map userMap = new HashMap<>(); + + private UserManager() { + instance = this; + } + + public RixaUser getUser(User user) { + if (hasUser(user.getId())) + return userMap.get(user.getId()); + RixaUser rixaUser = new RixaUser(user); + addUser(rixaUser); + return rixaUser; + } + + public void addUser(RixaUser user) { + if (hasUser(user.getUser().getId())) return; + userMap.put(user.getUser().getId(), user); + } + + public void removeUser(String id) { + if (!hasUser(id)) return; + userMap.remove(id); + } + + public boolean hasUser(String id) { return userMap.containsKey(id); } + + public static UserManager getInstance() { + return (instance == null) ? new UserManager() : instance; + } +} diff --git a/src/main/java/io/rixa/bot/user/mapper/UserPermissionsMapper.java b/src/main/java/io/rixa/bot/user/mapper/UserPermissionsMapper.java new file mode 100644 index 0000000..764deb7 --- /dev/null +++ b/src/main/java/io/rixa/bot/user/mapper/UserPermissionsMapper.java @@ -0,0 +1,31 @@ +package io.rixa.bot.user.mapper; + +import io.rixa.bot.commands.perms.RixaPermission; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class UserPermissionsMapper implements ResultSetExtractor>>{ + @Override + public Map> extractData(ResultSet resultSet) throws SQLException, DataAccessException { + Map> permissionsMap = new HashMap<>(); + List permissions = new ArrayList<>(); + while (resultSet.next()) { + String guildId = resultSet.getString("guild_id"); + RixaPermission rixaPermission = RixaPermission.fromString(resultSet.getString("permission")); + + if (permissionsMap.containsKey(guildId)) permissions.addAll(permissionsMap.get(guildId)); + + if (!permissions.contains(rixaPermission)) permissions.add(rixaPermission); + permissionsMap.replace(guildId, permissions); + permissions.clear(); + } + return permissionsMap; + } +} diff --git a/src/main/java/io/rixa/bot/utils/DiscordUtils.java b/src/main/java/io/rixa/bot/utils/DiscordUtils.java index 71021df..328f225 100644 --- a/src/main/java/io/rixa/bot/utils/DiscordUtils.java +++ b/src/main/java/io/rixa/bot/utils/DiscordUtils.java @@ -104,4 +104,29 @@ public class DiscordUtils { voiceChannel.getName().contains(string)).findFirst(); return optional.orElse(null); } + + + + public static int getLevelFromExperience(int xp) { + int level = 0; + while (xp >= getNeededXP(level)) { + xp -= getNeededXP(level); + level++; + } + return level; + } + + public static Double getNeededXP(double n) { + if (n < 0) return 0.0; + return (6 * Math.pow(n, 3) + 119 * n + 100); + } + + public static int getRemainingExperience(int xp) { + int level = getLevelFromExperience(xp); + + for (int i = 0; i < level; i++) { + xp -= getNeededXP(i); + } + return xp; + } } diff --git a/src/main/java/io/rixa/bot/utils/MessageFactory.java b/src/main/java/io/rixa/bot/utils/MessageFactory.java index 96e6832..1114683 100644 --- a/src/main/java/io/rixa/bot/utils/MessageFactory.java +++ b/src/main/java/io/rixa/bot/utils/MessageFactory.java @@ -10,9 +10,12 @@ import net.dv8tion.jda.core.exceptions.PermissionException; import net.dv8tion.jda.core.exceptions.RateLimitedException; import java.awt.*; +import java.time.OffsetDateTime; +import java.time.OffsetTime; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; public class MessageFactory { @@ -72,20 +75,37 @@ public class MessageFactory { return this; } + public MessageFactory setTimestamp() { + builder.setTimestamp(OffsetDateTime.now()); + return this; + } + public MessageFactory setAuthor(String name, String iconURL) { builder.setAuthor(name, iconURL, iconURL); return this; } - public void queue(TextChannel channel) { + public MessageFactory queue(TextChannel channel, Consumer success) { try { - message = channel.sendMessage(builder.build()).complete(true); + success.andThen(successMessage -> { + this.message = successMessage; + destroy(); + }); + channel.sendMessage(builder.build()).queue(success); + } catch (PermissionException ex) { + System.out.println("I do not have permission: " + ex.getPermission().getName() + " on server " + channel.getGuild().getName() + " in channel: " + channel.getName()); + } + return this; + } + + public MessageFactory queue(TextChannel channel) { + try { + channel.sendMessage(builder.build()).queue(successMessage -> this.message = successMessage); destroy(); } catch (PermissionException ex) { System.out.println("I do not have permission: " + ex.getPermission().getName() + " on server " + channel.getGuild().getName() + " in channel: " + channel.getName()); - } catch (RateLimitedException e) { - e.printStackTrace(); } + return this; } public Message complete(TextChannel channel) { @@ -104,8 +124,13 @@ public class MessageFactory { destroy(); } + public void send(User member, Consumer success) { + success.andThen(message -> this.message = message); + member.openPrivateChannel().queue(s -> s.sendMessage(builder.build()).queue(success)); + } + public MessageFactory sendUser(User member) { - this.message = member.openPrivateChannel().complete().sendMessage(builder.build()).complete(); + member.openPrivateChannel().complete().sendMessage(builder.build()).queue(message1 -> this.message = message1); destroy(); return this; } @@ -114,7 +139,7 @@ public class MessageFactory { if(message == null) { throw new NullPointerException("Message must not be null!"); } - message.addReaction(reaction).complete(); + message.addReaction(reaction).queue(); return this; }