From ab37109100fe62aca61a9e05e60ab93e46688dee Mon Sep 17 00:00:00 2001 From: Matheus Date: Tue, 12 Mar 2024 06:42:31 -0400 Subject: [PATCH] Added leaderboards system, and added some changes to Main.java & ProfileKitData.java to support leaderboards --- src/main/java/dev/lugami/otaku/Main.java | 4 +- .../otaku/commands/LeaderboardsCommand.java | 14 +++ .../otaku/leaderboards/Leaderboards.java | 102 ++++++++++++++++++ .../otaku/leaderboards/LeaderboardsEntry.java | 15 +++ .../leaderboards/menu/LeaderboardsMenu.java | 78 ++++++++++++++ .../otaku/profile/data/ProfileKitData.java | 3 + 6 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 src/main/java/dev/lugami/otaku/commands/LeaderboardsCommand.java create mode 100644 src/main/java/dev/lugami/otaku/leaderboards/Leaderboards.java create mode 100644 src/main/java/dev/lugami/otaku/leaderboards/LeaderboardsEntry.java create mode 100644 src/main/java/dev/lugami/otaku/leaderboards/menu/LeaderboardsMenu.java diff --git a/src/main/java/dev/lugami/otaku/Main.java b/src/main/java/dev/lugami/otaku/Main.java index 156e803..84a0b88 100644 --- a/src/main/java/dev/lugami/otaku/Main.java +++ b/src/main/java/dev/lugami/otaku/Main.java @@ -12,6 +12,7 @@ import dev.lugami.otaku.commands.kit.*; import dev.lugami.otaku.essentials.Essentials; import dev.lugami.otaku.hotbar.Hotbar; import dev.lugami.otaku.kit.Kit; +import dev.lugami.otaku.leaderboards.Leaderboards; import dev.lugami.otaku.listener.FFAListener; import dev.lugami.otaku.listener.GeneralListeners; import dev.lugami.otaku.profile.Profile; @@ -68,8 +69,9 @@ public class Main extends JavaPlugin { Kit.init(); Hotbar.init(); Profile.init(); + Leaderboards.setup(); Arrays.asList(new FFAListener(), new GeneralListeners(), new ProfileListener(), new MenuListener()).forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, this)); - Arrays.asList(new OtakuCommand(), new FFACommand(), new FFASetSpawnCommand(), new KitSetIconCommand(), new KitCreateCommand(), new KitDeleteCommand(), new KitGetLoadoutCommand(), new KitSetLoadoutCommand(), new KitsCommand(), new KitSetLocationCommand(), new MainMenuCommand(), new FFAJoinCommand(), new FFAQuitCommand(), new KitCommand(), new ReKitCommand()).forEach(command -> honcho.registerCommand(command)); + Arrays.asList(new OtakuCommand(), new FFACommand(), new FFASetSpawnCommand(), new KitSetIconCommand(), new KitCreateCommand(), new KitDeleteCommand(), new KitGetLoadoutCommand(), new KitSetLoadoutCommand(), new KitsCommand(), new KitSetLocationCommand(), new MainMenuCommand(), new FFAJoinCommand(), new FFAQuitCommand(), new KitCommand(), new ReKitCommand(), new LeaderboardsCommand()).forEach(command -> honcho.registerCommand(command)); getServer().getWorlds().forEach(essentials::clearEntities); } diff --git a/src/main/java/dev/lugami/otaku/commands/LeaderboardsCommand.java b/src/main/java/dev/lugami/otaku/commands/LeaderboardsCommand.java new file mode 100644 index 0000000..ab576f5 --- /dev/null +++ b/src/main/java/dev/lugami/otaku/commands/LeaderboardsCommand.java @@ -0,0 +1,14 @@ +package dev.lugami.otaku.commands; + +import com.qrakn.honcho.command.CommandMeta; +import dev.lugami.otaku.leaderboards.menu.LeaderboardsMenu; +import org.bukkit.entity.Player; + +@CommandMeta(label = "leaderboards") +public class LeaderboardsCommand { + + public void exec(Player player) { + new LeaderboardsMenu().openMenu(player); + } + +} diff --git a/src/main/java/dev/lugami/otaku/leaderboards/Leaderboards.java b/src/main/java/dev/lugami/otaku/leaderboards/Leaderboards.java new file mode 100644 index 0000000..72a1718 --- /dev/null +++ b/src/main/java/dev/lugami/otaku/leaderboards/Leaderboards.java @@ -0,0 +1,102 @@ +package dev.lugami.otaku.leaderboards; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import dev.lugami.otaku.Main; +import dev.lugami.otaku.kit.Kit; +import dev.lugami.otaku.profile.Profile; +import dev.lugami.otaku.profile.data.ProfileKitData; +import dev.lugami.otaku.utils.SaveMethodType; +import dev.lugami.otaku.utils.TaskUtil; +import lombok.Getter; +import org.bson.Document; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; + +public class Leaderboards { + + @Getter private static final Map> leaderboards = Maps.newHashMap(); + + public static void setup() { + updateLeaderboards(); + TaskUtil.runTimerAsync(new BukkitRunnable() { + @Override + public void run() { + updateLeaderboards(); + } + }, 0L, 600L); + } + + private static List getSortedPlayers(Kit ladder) { + try { + Document sort = new Document(); + sort.put("kitStatistics." + ladder.getName() + ".kills", -1); + return Main.getInstance().getMongoDatabase().getCollection("profiles").find().sort(sort).limit(10).into(new ArrayList<>()); + } catch (Exception ex) { + return null; + } + } + + private static Map getSortedPlayers_ff(Kit ladder) { + Map map = new HashMap<>(); + ConfigurationSection main = Main.getInstance().getProfileConfig().getConfiguration().getConfigurationSection("stats"); + for (String name : main.getKeys(false)) { + ConfigurationSection playerSection = main.getConfigurationSection(name); + if (playerSection != null && playerSection.contains(ladder.getName())) { + ConfigurationSection kitSection = playerSection.getConfigurationSection(ladder.getName()); + int kills = kitSection.getInt("kills"); + int killstreak = kitSection.getInt("killstreak"); + int deaths = kitSection.getInt("deaths"); + ProfileKitData data = new ProfileKitData(kills, killstreak, deaths); + map.put(name, data); + } + } + List> list = new ArrayList<>(map.entrySet()); + Comparator> comparator = Comparator.comparing(entry -> entry.getValue().kills()); + list.sort(comparator.reversed()); + int maxSize = Math.min(10, list.size()); + list = list.subList(0, maxSize); + Map sortedMap = new LinkedHashMap<>(); + for (Map.Entry entry : list) { + sortedMap.put(entry.getKey(), entry.getValue()); + } + return sortedMap; + } + + private static void updateLeaderboards() { + leaderboards.clear(); + Kit.getKits().forEach(kit -> { + List entry = Lists.newArrayList(); + if (Main.getInstance().getSaveMethodType() == SaveMethodType.MONGO && Profile.getCollection() != null) { + List sortedPlayers = getSortedPlayers(kit); + + if (sortedPlayers != null) { + sortedPlayers.forEach(document -> { + UUID uuid = UUID.fromString(document.getString("uuid")); + Document kitStatistics = (Document) document.get("kitStatistics"); + Document kitDocument = (Document) kitStatistics.get(kit.getName()); + Integer kills = (kitDocument != null) ? kitDocument.getInteger("kills") : null; + Integer killstreak = (kitDocument != null) ? kitDocument.getInteger("killstreak") : null; + Integer deaths = (kitDocument != null) ? kitDocument.getInteger("deaths") : null; + + // Use a default value if elo is null + kills = (kills != null) ? kills : 0; + deaths = (deaths != null) ? deaths : 0; + killstreak = (killstreak != null) ? killstreak : 0; + + entry.add(new LeaderboardsEntry(Bukkit.getOfflinePlayer(uuid).getName(), kills, killstreak, deaths)); + }); + leaderboards.put(kit, entry); + } + } else { + Map sorted = getSortedPlayers_ff(kit); + sorted.forEach((sort, data) -> entry.add(new LeaderboardsEntry(sort, data.kills(), data.killstreak(), data.deaths()))); + leaderboards.put(kit, entry); + } + }); + } + +} diff --git a/src/main/java/dev/lugami/otaku/leaderboards/LeaderboardsEntry.java b/src/main/java/dev/lugami/otaku/leaderboards/LeaderboardsEntry.java new file mode 100644 index 0000000..4f5e075 --- /dev/null +++ b/src/main/java/dev/lugami/otaku/leaderboards/LeaderboardsEntry.java @@ -0,0 +1,15 @@ +package dev.lugami.otaku.leaderboards; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data @Accessors(fluent = true) @AllArgsConstructor +public class LeaderboardsEntry { + + private String name; + private int kills; + private int killstreak; + private int deaths; + +} diff --git a/src/main/java/dev/lugami/otaku/leaderboards/menu/LeaderboardsMenu.java b/src/main/java/dev/lugami/otaku/leaderboards/menu/LeaderboardsMenu.java new file mode 100644 index 0000000..4ef2bbd --- /dev/null +++ b/src/main/java/dev/lugami/otaku/leaderboards/menu/LeaderboardsMenu.java @@ -0,0 +1,78 @@ +package dev.lugami.otaku.leaderboards.menu; + +import dev.lugami.otaku.Constants; +import dev.lugami.otaku.kit.Kit; +import dev.lugami.otaku.leaderboards.Leaderboards; +import dev.lugami.otaku.leaderboards.LeaderboardsEntry; +import dev.lugami.otaku.utils.CC; +import dev.lugami.otaku.utils.ItemBuilder; +import dev.lugami.otaku.utils.menu.Button; +import dev.lugami.otaku.utils.menu.Menu; +import lombok.AllArgsConstructor; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class LeaderboardsMenu extends Menu { + + @Override + public String getTitle(Player player) { + return "&7Leaderboards"; + } + + @Override + public int getSize(){ + int i = 3; + if (Kit.getKits().size() - 1 > 7) { + i = 4; + } + if (Kit.getKits().size() - 1 > 14) { + i = 5; + } + return 9*i; + } + + @Override + public Map getButtons(Player player) { + Map buttons = new HashMap<>(); + for (int i = 0; i < getSize(); i++) { + buttons.put(i, Constants.getPlaceholder()); + } + final int[] i = {10}; + Kit.getKits().forEach(kit -> { + if (!kit.isEnabled()) return; + while (i[0] == 17 || i[0] == 18 || i[0] == 26 || i[0] == 27 || i[0] == 36 || i[0] == 37) i[0]++; + buttons.put(i[0]++, new KitStatsButton(kit)); + }); + + return buttons; + } + + @AllArgsConstructor + private class KitStatsButton extends Button { + + private final Kit kit; + + @Override + public ItemStack getButtonItem(Player player) { + List lore = new ArrayList<>(); + lore.add(CC.MENU_BAR); + int pos = 1; + for (LeaderboardsEntry entry : Leaderboards.getLeaderboards().get(kit)) { + lore.add("&b" +pos + ". " + entry.name() + "&7 - " + entry.kills() + "/" + entry.killstreak() + "/" + entry.deaths()); + pos++; + } + lore.add(CC.MENU_BAR); + + return new ItemBuilder(kit.getDisplayIcon()) + .name("&b" + kit.getName() + " &7⏐ &fStats") + .lore(lore) + .build(); + } + + } +} diff --git a/src/main/java/dev/lugami/otaku/profile/data/ProfileKitData.java b/src/main/java/dev/lugami/otaku/profile/data/ProfileKitData.java index 11fa7b2..da26bff 100644 --- a/src/main/java/dev/lugami/otaku/profile/data/ProfileKitData.java +++ b/src/main/java/dev/lugami/otaku/profile/data/ProfileKitData.java @@ -1,9 +1,12 @@ package dev.lugami.otaku.profile.data; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import lombok.experimental.Accessors; @Data @Accessors(fluent = true) +@AllArgsConstructor @NoArgsConstructor public class ProfileKitData { private int kills;