diff --git a/src/main/java/de/voidtech/gerald/commands/utils/ExperienceCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/ExperienceCommand.java index 7fa9f312..1dc9a608 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/ExperienceCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/ExperienceCommand.java @@ -1,6 +1,7 @@ package main.java.de.voidtech.gerald.commands.utils; import java.awt.Color; +import java.util.Arrays; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; @@ -18,7 +19,6 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.entities.MessageEmbed; @Command @@ -33,55 +33,87 @@ public class ExperienceCommand extends AbstractCommand { @Override public void executeInternal(CommandContext context, List args) { Server server = serverService.getServer(context.getGuild().getId()); - if (args.isEmpty()) sendLevelCard(context.getChannel(), context.getMember(), server.getId()); + if (args.isEmpty()) sendLevelCard(context, context.getMember(), server.getId()); else { String ID = ParsingUtils.filterSnowflake(args.get(0)); if (ParsingUtils.isSnowflake(ID)) { - Member mentionedMember = context.getGuild().getMemberById(ID); + Member mentionedMember = context.getGuild().retrieveMemberById(ID).complete(); if (mentionedMember == null) context.getChannel().sendMessage("**You need to mention another member to see their XP!**").queue(); - else sendLevelCard(context.getChannel(), mentionedMember, server.getId()); + else sendLevelCard(context, mentionedMember, server.getId()); } else { switch (args.get(0)) { case "levels": - showAllLevelRoles(context.getChannel(), server, context.getGuild()); + showAllLevelRoles(context, server, context.getGuild()); break; case "addrole": - addLevelUpRole(context.getChannel(), args, server); + addLevelUpRole(context, args, server); break; case "removerole": - removeLevelUpRole(context.getChannel(), args, server); + removeLevelUpRole(context, args, server); + break; + case "leaderboard": + showServerLeaderboard(context, server); + break; + case "lb": + showServerLeaderboard(context, server); break; } } } } - private void addLevelUpRole(MessageChannel channel, List args, Server server) { + private void showServerLeaderboard(CommandContext context, Server server) { + List topTenMembers = xpService.getServerLeaderboardChunk(server.getId(), 10, 0); + int userPosition = xpService.getUserLeaderboardPosition(server.getId(), context.getAuthor().getId()); + Experience userXP = xpService.getUserExperience(context.getAuthor().getId(), server.getId()); + + String leaderboard = ""; + int rank = 1; + + for (Experience xp : topTenMembers) { + leaderboard += numberToEmoji(rank) + " <@" + xp.getUserID() + ">\n"; + leaderboard += "```js\nLevel " + xp.getCurrentLevel() + " | XP " + xp.getTotalExperience() + "\n```"; + rank++; + } + + leaderboard += "\n**Your Position**\n"; + leaderboard += numberToEmoji(userPosition) + " <@" + userXP.getUserID() + ">\n"; + leaderboard += "```js\nLevel " + userXP.getCurrentLevel() + " | XP " + userXP.getTotalExperience() + "\n```"; + + MessageEmbed leaderboardEmbed = new EmbedBuilder() + .setColor(Color.ORANGE) + .setDescription(leaderboard) + .setTitle(context.getGuild().getName() + "'s Most Active Members") + .build(); + context.reply(leaderboardEmbed); + } + + private void addLevelUpRole(CommandContext context, List args, Server server) { if (args.size() < 3) { - channel.sendMessage("**You need to supply more arguments! Make sure you have a level and a role mention or ID!**").queue(); + context.reply("**You need to supply more arguments! Make sure you have a level and a role mention or ID!**"); return; } String level = args.get(1); if (!ParsingUtils.isInteger(level)) { - channel.sendMessage("**You need to provide a valid number for the level!**").queue(); + context.reply("**You need to provide a valid number for the level!**"); return; } if (xpService.serverHasRoleForLevel(server.getId(), Integer.parseInt(level))) { - channel.sendMessage("**There is already a role set up for this level!**").queue(); + context.reply("**There is already a role set up for this level!**"); return; } String roleID = ParsingUtils.filterSnowflake(args.get(2)); if (!ParsingUtils.isSnowflake(roleID)) { - channel.sendMessage("**Please provide a valid role mention or role ID**").queue(); + context.reply("**Please provide a valid role mention or role ID**"); return; } - Guild guild = channel.getJDA().getGuildById(server.getGuildID()); + Guild guild = context.getJDA().getGuildById(server.getGuildID()); if (guild.getRoleById(roleID) == null) { - channel.sendMessage("**Please provide a valid role mention or role ID**").queue(); + context.reply("**Please provide a valid role mention or role ID**"); return; } @@ -92,23 +124,61 @@ private void addLevelUpRole(MessageChannel channel, List args, Server se .setTitle("Added Level Up Role!") .setDescription("Level: `" + level + "`\nRole: <@&" + roleID + ">") .build(); - channel.sendMessageEmbeds(newRoleEmbed).queue(); + context.reply(newRoleEmbed); + } + + private String numberToEmoji(int number) { + List digits = Arrays.asList(String.valueOf(number).split("")); //Wowzer + String finalNumber = ""; + for (String digit : digits) { + finalNumber += convertSingleDigitToEmoji(digit); + } + return finalNumber; + } + + private String convertSingleDigitToEmoji(String digit) { + switch (digit) { + case "0": + return ":zero"; + case "1": + return ":one:"; + case "2": + return ":two:"; + case "3": + return ":three:"; + case "4": + return ":four:"; + case "5": + return ":five:"; + case "6": + return ":six:"; + case "7": + return ":seven:"; + case "8": + return ":eight:"; + case "9": + return ":nine:"; + case "10": + return ":ten:"; + default: + return ":zero:"; + } } - private void removeLevelUpRole(MessageChannel channel, List args, Server server) { + private void removeLevelUpRole(CommandContext context, List args, Server server) { if (args.size() < 2) { - channel.sendMessage("**You need to provide a level to remove the role from!**").queue(); + context.reply("**You need to provide a level to remove the role from!**"); return; } String level = args.get(1); if (!ParsingUtils.isInteger(level)) { - channel.sendMessage("**You need to provide a valid number for the level!**").queue(); + context.reply("**You need to provide a valid number for the level!**"); return; } if (!xpService.serverHasRoleForLevel(server.getId(), Integer.parseInt(level))) { - channel.sendMessage("**There isn't a role set up for this level!**").queue(); + context.reply("**There isn't a role set up for this level!**"); return; } @@ -118,13 +188,13 @@ private void removeLevelUpRole(MessageChannel channel, List args, Server .setTitle("Removed Level Up Role!") .setDescription("Role for level `" + level + "` has been removed") .build(); - channel.sendMessageEmbeds(roleDeletedEmbed).queue(); + context.reply(roleDeletedEmbed); } - private void showAllLevelRoles(MessageChannel channel, Server server, Guild guild) { + private void showAllLevelRoles(CommandContext context, Server server, Guild guild) { List levelUpRoles = xpService.getAllLevelUpRolesForServer(server.getId()); if (levelUpRoles.isEmpty()) - channel.sendMessage("**There are no level roles set up in this server! See the help page for more info!**").queue(); + context.reply("**There are no level roles set up in this server! See the help page for more info!**"); else { String roleMessage = ""; for (LevelUpRole role : levelUpRoles) { @@ -135,18 +205,18 @@ private void showAllLevelRoles(MessageChannel channel, Server server, Guild guil .setTitle("Level up roles for " + guild.getName()) .setDescription(roleMessage) .build(); - channel.sendMessageEmbeds(levelRolesEmbed).queue(); + context.reply(levelRolesEmbed); } } - private void sendLevelCard(MessageChannel channel, Member member, long serverID) { + private void sendLevelCard(CommandContext context, Member member, long serverID) { Experience userXP = xpService.getUserExperience(member.getId(), serverID); byte[] xpCard = xpService.getExperienceCard(member.getUser().getAvatarUrl(), userXP.getCurrentExperience(), xpService.xpNeededForLevel(userXP.getNextLevel()), userXP.getCurrentLevel(), 1, member.getUser().getName() + "#" + member.getUser().getDiscriminator(), "#FF0000", "#2E2E2E"); - channel.sendFile(xpCard, "xpcard.png").queue(); + context.replyWithFile(xpCard, "xpcard.png"); } @Override diff --git a/src/main/java/de/voidtech/gerald/entities/Experience.java b/src/main/java/de/voidtech/gerald/entities/Experience.java index 8ac23cab..d569fbb4 100644 --- a/src/main/java/de/voidtech/gerald/entities/Experience.java +++ b/src/main/java/de/voidtech/gerald/entities/Experience.java @@ -83,6 +83,10 @@ public long getCurrentExperience() { return this.experienceGainedToNextLevel; } + public long getTotalExperience() { + return this.totalExperience; + } + public long getLastMessageTime() { return this.lastMessageTime; } diff --git a/src/main/java/de/voidtech/gerald/service/ExperienceService.java b/src/main/java/de/voidtech/gerald/service/ExperienceService.java index 57ffe146..cd67f694 100644 --- a/src/main/java/de/voidtech/gerald/service/ExperienceService.java +++ b/src/main/java/de/voidtech/gerald/service/ExperienceService.java @@ -43,7 +43,7 @@ public class ExperienceService { public byte[] getExperienceCard(String avatarURL, long xpAchieved, long xpNeeded, long level, long rank, String username, String barColour, String background) { try { - String cardURL = config.getExperienceCardApiURL() + "?avatar_url=" + avatarURL + + String cardURL = config.getExperienceCardApiURL() + "xpcard/?avatar_url=" + avatarURL + "&xp=" + xpAchieved + "&xp_needed=" + xpNeeded + "&level=" + level + "&rank=" + rank + "&username=" + URLEncoder.encode(username, StandardCharsets.UTF_8.toString()) + "&bar_colour=" + URLEncoder.encode(barColour, StandardCharsets.UTF_8.toString()) @@ -91,6 +91,43 @@ private ServerExperienceConfig getServerExperienceConfig(long serverID) { } } + public List getServerLeaderboard(long serverID) { + try(Session session = sessionFactory.openSession()) + { + @SuppressWarnings("unchecked") + List leaderboard = session.createQuery("FROM Experience WHERE serverID = :serverID ORDER BY totalExperience DESC") + .setParameter("serverID", serverID) + .list(); + return leaderboard; + } + } + + public List getServerLeaderboardChunk(long serverID, int limit, int offset) { + try(Session session = sessionFactory.openSession()) + { + @SuppressWarnings("unchecked") + List leaderboard = session.createQuery("FROM Experience WHERE serverID = :serverID ORDER BY totalExperience DESC") + .setParameter("serverID", serverID) + .setMaxResults(limit) + .setFirstResult(offset) + .list(); + return leaderboard; + } + } + + public int getUserLeaderboardPosition(long serverID, String userID) { + List leaderboard = getServerLeaderboard(serverID); + int position = 0; + boolean found = false; + + while (!found & leaderboard.iterator().hasNext()) { + position++; + if (leaderboard.iterator().next().getUserID().equals(userID)) found = true; + } + + return position; + } + private List getRolesForLevelFromServer(long id, long level) { try(Session session = sessionFactory.openSession()) { @@ -166,7 +203,7 @@ public void removeLevelUpRole(long level, long serverID) { } public long xpNeededForLevel(long level) { - return 5 * (level ^ 2) + (50 * level) + 100; + return (long) Math.ceil(Math.sqrt(5000 * (Math.pow(level, 3)))); } private long xpToNextLevel(long nextLevel, long currentXP) {