diff --git a/PhantomVoting/dependency-reduced-pom.xml b/PhantomVoting/dependency-reduced-pom.xml index 0b12192..b0eeafe 100644 --- a/PhantomVoting/dependency-reduced-pom.xml +++ b/PhantomVoting/dependency-reduced-pom.xml @@ -36,10 +36,6 @@ true - - dev.jorel.commandapi - me.fergs.commandapi - org.bstats me.bstats @@ -50,14 +46,14 @@ - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - maven-central https://oss.sonatype.org/content/groups/public + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + bencodez repo https://nexus.bencodez.com/repository/maven-public/ @@ -90,12 +86,6 @@ 2.11.6 provided - - dev.jorel - commandapi-bukkit-core - 10.1.2 - provided - com.mojang authlib diff --git a/PhantomVoting/pom.xml b/PhantomVoting/pom.xml index b5f0107..718eca1 100644 --- a/PhantomVoting/pom.xml +++ b/PhantomVoting/pom.xml @@ -43,11 +43,6 @@ true - - - dev.jorel.commandapi - me.fergs.commandapi - org.bstats @@ -66,14 +61,14 @@ - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - maven-central https://oss.sonatype.org/content/groups/public + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + bencodez repo https://nexus.bencodez.com/repository/maven-public/ @@ -107,17 +102,6 @@ 2.11.6 provided - - dev.jorel - commandapi-bukkit-core - 10.1.2 - provided - - - dev.jorel - commandapi-bukkit-shade - 10.1.2 - org.bstats bstats-bukkit diff --git a/PhantomVoting/src/main/java/me/fergs/phantomvoting/PhantomVoting.java b/PhantomVoting/src/main/java/me/fergs/phantomvoting/PhantomVoting.java index 612fa53..0ad0ff6 100644 --- a/PhantomVoting/src/main/java/me/fergs/phantomvoting/PhantomVoting.java +++ b/PhantomVoting/src/main/java/me/fergs/phantomvoting/PhantomVoting.java @@ -1,9 +1,6 @@ package me.fergs.phantomvoting; -import dev.jorel.commandapi.CommandAPI; -import dev.jorel.commandapi.CommandAPIBukkitConfig; -import me.fergs.phantomvoting.commands.AdminCommands; -import me.fergs.phantomvoting.commands.PlayerCommands; +import me.fergs.phantomvoting.commands.impl.CommandManager; import me.fergs.phantomvoting.config.ConfigurationManager; import me.fergs.phantomvoting.database.VoteStorage; import me.fergs.phantomvoting.inventories.LeaderboardInventory; @@ -35,16 +32,8 @@ public final class PhantomVoting extends JavaPlugin { private VoteReminderManager voteReminderManager; private MilestonesInventory milestonesInventory; private StreaksInventory streaksInventory; - /** - * Called when the plugin is loaded. - * This is where we register the Command API if it is not already loaded. - */ - @Override - public void onLoad() { - if (!CommandAPI.isLoaded()) { - CommandAPI.onLoad(new CommandAPIBukkitConfig(this).verboseOutput(false)); - } - } + private CommandManager commandManager; + @Override public void onEnable() { instance = this; @@ -89,8 +78,8 @@ public void onEnable() { new PlaceholderManager(voteStorage, votePartyManager).register(); } - new PlayerCommands().register(this); - new AdminCommands().register(this); + commandManager = new CommandManager(this); + commandManager.registerCommands(); if (configurationManager.isModuleEnabled("bossbar")) { bossbarManager = new BossbarManager<>(this); @@ -109,6 +98,7 @@ public void onEnable() { new Metrics(this, 23888); } + @Override public void onDisable() { try { @@ -123,6 +113,7 @@ public void onDisable() { voteReminderManager.cancelAllTasks(); } } + /** * Gets the plugin instance. * @@ -130,7 +121,9 @@ public void onDisable() { */ public static PhantomVoting getInstance() { return instance; - }/** + } + + /** * Gets the configuration manager. * * @return the configuration manager @@ -138,6 +131,7 @@ public static PhantomVoting getInstance() { public ConfigurationManager getConfigurationManager() { return configurationManager; } + /** * Gets the message manager. * @@ -146,6 +140,7 @@ public ConfigurationManager getConfigurationManager() { public MessageManager getMessageManager() { return messageManager; } + /** * Gets the vote storage. * @@ -154,6 +149,7 @@ public MessageManager getMessageManager() { public VoteStorage getVoteStorage() { return voteStorage; } + /** * Gets the vote party manager. * @@ -162,6 +158,7 @@ public VoteStorage getVoteStorage() { public VotePartyManager getVotePartyManager() { return votePartyManager; } + /** * Gets the listener manager. * @@ -170,6 +167,7 @@ public VotePartyManager getVotePartyManager() { public ListenerManager getListenerManager() { return listenerManager; } + /** * Gets the player manager. * @@ -178,6 +176,7 @@ public ListenerManager getListenerManager() { public PlayerManager getPlayerManager() { return playerManager; } + /** * Gets the bossbar manager. * @@ -186,6 +185,7 @@ public PlayerManager getPlayerManager() { public BossbarManager getBossbarManager() { return bossbarManager; } + /** * Gets the leaderboard inventory. * @@ -194,6 +194,7 @@ public BossbarManager getBossbarManager() { public LeaderboardInventory getLeaderboardInventory() { return leaderboardInventory; } + /** * Gets the vote reminder manager. * @@ -202,6 +203,7 @@ public LeaderboardInventory getLeaderboardInventory() { public VoteReminderManager getVoteReminderManager() { return voteReminderManager; } + /** * Gets the milestones inventory. * @@ -210,6 +212,7 @@ public VoteReminderManager getVoteReminderManager() { public MilestonesInventory getMilestonesInventory() { return milestonesInventory; } + /** * Gets the streaks inventory. * diff --git a/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/AdminCommands.java b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/AdminCommands.java index 7477604..428552e 100644 --- a/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/AdminCommands.java +++ b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/AdminCommands.java @@ -2,177 +2,446 @@ import com.vexsoftware.votifier.model.Vote; import com.vexsoftware.votifier.model.VotifierEvent; -import dev.jorel.commandapi.CommandAPICommand; -import dev.jorel.commandapi.arguments.*; import me.fergs.phantomvoting.PhantomVoting; +import me.fergs.phantomvoting.commands.impl.CommandArguments; +import me.fergs.phantomvoting.commands.impl.CommandManager; +import me.fergs.phantomvoting.commands.impl.CustomCommand; import me.fergs.phantomvoting.utils.Color; import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; public class AdminCommands { /** * Registers the admin commands. * * @param plugin The plugin instance. + * @param commandManager The command manager. */ - public void register(final PhantomVoting plugin) { - new CommandAPICommand(plugin.getConfigurationManager().getConfig("config").getString("Commands.Admin.Base", "phantomvoting")) - .withAliases(plugin.getConfigurationManager().getConfig("config").getStringList("Commands.Admin.Aliases").toArray(new String[0])) - .withPermission("phantomvoting.admin") - .executes((player, args) -> { - plugin.getMessageManager().sendMessage(player, "ADMIN_HELP", "%admin_command%", plugin.getConfigurationManager().getConfig("config").getString("Commands.Admin.Base", "phantomvoting")); + public void register(final PhantomVoting plugin, CommandManager commandManager) { + String baseCommand = plugin.getConfigurationManager().getConfig("config").getString("Commands.Admin.Base", "phantomvoting"); + List aliases = plugin.getConfigurationManager().getConfig("config").getStringList("Commands.Admin.Aliases"); + + commandManager.registerCommand( + new CustomCommand(baseCommand, "PhantomVoting admin command", "/" + baseCommand, aliases) + .withPermission("phantomvoting.admin") + .executes((CommandSender sender, CommandArguments args) -> + plugin.getMessageManager().sendMessage(sender, "ADMIN_HELP", "%admin_command%", baseCommand)) + .withSubcommand(createReloadCommand(plugin)) + .withSubcommand(createGiveVoteCommand(plugin, baseCommand)) + .withSubcommand(createTestVoteCommand(plugin, baseCommand)) + .withSubcommand(createRemoveVoteCommand(plugin, baseCommand)) + .withSubcommand(createVotePartyCommand(plugin, baseCommand)) + .withSubcommand(createStreaksCommand(plugin, baseCommand)) + .withSubcommand(createOpenGuiCommand(plugin, baseCommand)) + ); + } + + /** + * Creates the reload subcommand. + */ + private CustomCommand createReloadCommand(PhantomVoting plugin) { + return new CustomCommand("reload") + .executes((sender, args) -> { + plugin.getConfigurationManager().reloadAllConfigs(); + plugin.getVotePartyManager().reloadSettings(); + plugin.getLeaderboardInventory().reloadInventory(); + + if (plugin.getConfigurationManager().isModuleEnabled("Milestones")) { + plugin.getMilestonesInventory().reloadInventory(); + } + if (plugin.getConfigurationManager().isModuleEnabled("VoteReminder")) { + plugin.getVoteReminderManager().reloadTask("VoteReminder"); + } + if (plugin.getConfigurationManager().isModuleEnabled("Streaks-Menu")) { + plugin.getStreaksInventory().reloadInventory(); + } + + plugin.getMessageManager().sendMessage(sender, "RELOAD"); + }); + } + + /** + * Creates the givevote subcommand. + */ + private CustomCommand createGiveVoteCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("givevote") + .withTabCompleter((sender, args) -> { + if (args.length == 1) { + String partial = args[0].toLowerCase(); + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(partial)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); }) - .withSubcommand(new CommandAPICommand("reload") - .executes((player, args) -> { - plugin.getConfigurationManager().reloadAllConfigs(); - plugin.getVotePartyManager().reloadSettings(); - plugin.getLeaderboardInventory().reloadInventory(); + .executes((sender, args) -> { + if (args.size() < 2) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " givevote ")); + return; + } + + Player target = args.getPlayer(0); + Integer amount = args.getInt(1); + + if (target == null) { + sender.sendMessage(Color.hex("&cPlayer not found!")); + return; + } + if (amount == null || amount <= 0) { + sender.sendMessage(Color.hex("&cAmount must be a positive number!")); + return; + } + + plugin.getVoteStorage().addMultipleVotes(target.getUniqueId(), amount); + plugin.getMessageManager().sendMessage(sender, "GIVE_VOTE", + "%player%", target.getName(), + "%amount%", String.valueOf(amount)); + }); + } + + /** + * Creates the testvote subcommand. + */ + private CustomCommand createTestVoteCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("testvote") + .withTabCompleter((sender, args) -> { + if (args.length == 1) { + String partial = args[0].toLowerCase(); + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(partial)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + }) + .executes((sender, args) -> { + if (args.size() < 1) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " testvote ")); + return; + } + + Player target = args.getPlayer(0); + if (target == null) { + sender.sendMessage(Color.hex("&cPlayer not found!")); + return; + } + + Vote vote = new Vote("TestVote", target.getName(), "127.0.0.1", + Long.toString(System.currentTimeMillis(), 10)); + Bukkit.getPluginManager().callEvent(new VotifierEvent(vote)); + }); + } + + /** + * Creates the removevote subcommand. + */ + private CustomCommand createRemoveVoteCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("removevote") + .withTabCompleter((sender, args) -> { + if (args.length == 1) { + String partial = args[0].toLowerCase(); + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(partial)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + }) + .executes((sender, args) -> { + if (args.size() < 2) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " removevote ")); + return; + } + + Player target = args.getPlayer(0); + Integer amount = args.getInt(1); + + if (target == null) { + sender.sendMessage(Color.hex("&cPlayer not found!")); + return; + } + if (amount == null || amount <= 0) { + sender.sendMessage(Color.hex("&cAmount must be a positive number!")); + return; + } + + plugin.getVoteStorage().removeVote(target.getUniqueId(), amount); + plugin.getMessageManager().sendMessage(sender, "REMOVE_VOTE", + "%player%", target.getName(), + "%amount%", String.valueOf(amount)); + }); + } + + /** + * Creates the voteparty command with subcommands. + */ + private CustomCommand createVotePartyCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("voteparty") + .withSubcommand(createVotePartyForceStartCommand(plugin)) + .withSubcommand(createVotePartyAddCommand(plugin, baseCommand)) + .withSubcommand(createVotePartySetCommand(plugin, baseCommand)); + } + + /** + * Creates the voteparty forcestart subcommand. + */ + private CustomCommand createVotePartyForceStartCommand(PhantomVoting plugin) { + return new CustomCommand("forcestart") + .withTabCompleter((sender, args) -> { + if (args.length == 1) { + String partial = args[0].toLowerCase(); + List options = Arrays.asList("true", "false"); + return options.stream() + .filter(opt -> opt.startsWith(partial)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + }) + .executes((sender, args) -> { + boolean resetVoteProgress = args.size() > 0 && + args.getBoolean(0) != null && + args.getBoolean(0); + plugin.getVotePartyManager().forceVoteParty(resetVoteProgress); + }); + } + + /** + * Creates the voteparty add subcommand. + */ + private CustomCommand createVotePartyAddCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("add") + .executes((sender, args) -> { + if (args.size() < 1) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " voteparty add ")); + return; + } + + Integer amount = args.getInt(0); + if (amount == null) { + sender.sendMessage(Color.hex("&cAmount must be a number!")); + return; + } + + plugin.getVotePartyManager().forceAddAmount(amount); + }); + } + + /** + * Creates the voteparty set subcommand. + */ + private CustomCommand createVotePartySetCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("set") + .executes((sender, args) -> { + if (args.size() < 1) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " voteparty set ")); + return; + } + + Integer amount = args.getInt(0); + if (amount == null) { + sender.sendMessage(Color.hex("&cAmount must be a number!")); + return; + } + + plugin.getVotePartyManager().setCurrentVoteCount(amount); + }); + } + + /** + * Creates the streaks command with subcommands. + */ + private CustomCommand createStreaksCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("streaks") + .withSubcommand(createStreaksResetCommand(plugin, baseCommand)) + .withSubcommand(createStreaksSetCommand(plugin, baseCommand)) + .withSubcommand(createStreaksAddCommand(plugin, baseCommand)); + } + + /** + * Creates the streaks reset subcommand. + */ + private CustomCommand createStreaksResetCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("reset") + .withTabCompleter((sender, args) -> { + if (args.length == 1) { + String partial = args[0].toLowerCase(); + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(partial)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + }) + .executes((sender, args) -> { + if (args.size() < 1) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " streaks reset ")); + return; + } + + Player target = args.getPlayer(0); + if (target == null) { + sender.sendMessage(Color.hex("&cPlayer not found!")); + return; + } + + LocalDate today = LocalDate.now(); + plugin.getVoteStorage().resetStreak(target.getUniqueId(), today.toString()); + plugin.getMessageManager().sendMessage(sender, "STREAK_RESET", "%player%", target.getName()); + }); + } + + /** + * Creates the streaks set subcommand. + */ + private CustomCommand createStreaksSetCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("set") + .withTabCompleter((sender, args) -> { + if (args.length == 1) { + String partial = args[0].toLowerCase(); + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(partial)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + }) + .executes((sender, args) -> { + if (args.size() < 2) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " streaks set ")); + return; + } + + Player target = args.getPlayer(0); + Integer streak = args.getInt(1); + + if (target == null) { + sender.sendMessage(Color.hex("&cPlayer not found!")); + return; + } + if (streak == null) { + sender.sendMessage(Color.hex("&cStreak must be a number!")); + return; + } + + plugin.getVoteStorage().setVoteStreak(target.getUniqueId(), streak); + plugin.getMessageManager().sendMessage(sender, "STREAK_SET", + "%player%", target.getName(), + "%streak%", String.valueOf(streak)); + }); + } + + /** + * Creates the streaks add subcommand. + */ + private CustomCommand createStreaksAddCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("add") + .withTabCompleter((sender, args) -> { + if (args.length == 1) { + String partial = args[0].toLowerCase(); + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(partial)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + }) + .executes((sender, args) -> { + if (args.size() < 2) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " streaks add ")); + return; + } + + Player target = args.getPlayer(0); + Integer streak = args.getInt(1); + + if (target == null) { + sender.sendMessage(Color.hex("&cPlayer not found!")); + return; + } + if (streak == null) { + sender.sendMessage(Color.hex("&cStreak must be a number!")); + return; + } + + plugin.getVoteStorage().addStreak(target.getUniqueId(), streak); + plugin.getMessageManager().sendMessage(sender, "STREAK_ADD", + "%player%", target.getName(), + "%streak%", String.valueOf(streak)); + }); + } + + /** + * Creates the opengui subcommand. + */ + private CustomCommand createOpenGuiCommand(PhantomVoting plugin, String baseCommand) { + return new CustomCommand("opengui") + .withTabCompleter((sender, args) -> { + if (args.length == 1) { + String partial = args[0].toLowerCase(); + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase().startsWith(partial)) + .collect(Collectors.toList()); + } else if (args.length == 2) { + String partial = args[1].toLowerCase(); + List guis = new ArrayList<>(Arrays.asList("leaderboard")); + if (plugin.getConfigurationManager().isModuleEnabled("Milestones")) { + guis.add("milestones"); + } + if (plugin.getConfigurationManager().isModuleEnabled("Streaks-Menu")) { + guis.add("streaks"); + } + return guis.stream() + .filter(gui -> gui.startsWith(partial)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + }) + .executes((sender, args) -> { + if (args.size() < 2) { + sender.sendMessage(Color.hex("&cUsage: /" + baseCommand + " opengui ")); + return; + } + + Player target = args.getPlayer(0); + String gui = args.getString(1); + + if (target == null) { + sender.sendMessage(Color.hex("&cPlayer not found!")); + return; + } + if (gui == null) { + sender.sendMessage(Color.hex("&4&l[&c&l!&4&l] &cThe GUI type does not exist.")); + return; + } + + switch (gui.toLowerCase()) { + case "leaderboard": + target.openInventory(plugin.getLeaderboardInventory().createInventory(target)); + break; + case "milestones": if (plugin.getConfigurationManager().isModuleEnabled("Milestones")) { - plugin.getMilestonesInventory().reloadInventory(); - } - if (plugin.getConfigurationManager().isModuleEnabled("VoteReminder")) { - plugin.getVoteReminderManager().reloadTask("VoteReminder"); + target.openInventory(plugin.getMilestonesInventory().createInventory(target)); } + break; + case "streaks": if (plugin.getConfigurationManager().isModuleEnabled("Streaks-Menu")) { - plugin.getStreaksInventory().reloadInventory(); - } - plugin.getMessageManager().sendMessage(player, "RELOAD"); - }) - ) - .withSubcommand(new CommandAPICommand("givevote") - .withArguments(new PlayerArgument("player"), new IntegerArgument("amount")) - .executes((player, args) -> { - Player target = (Player) args.get("player"); - int amount = (int) args.get("amount"); - assert target != null; - plugin.getVoteStorage().addMultipleVotes(target.getUniqueId(), amount); - plugin.getMessageManager().sendMessage(player, "GIVE_VOTE", "%player%", target.getName(), "%amount%", String.valueOf(amount)); - }) - ) - .withSubcommand(new CommandAPICommand("testvote") - .withArguments(new PlayerArgument("player")) - .executes((player, args) -> { - Player target = (Player) args.get("player"); - if (target == null) { - throw new IllegalArgumentException("Player not found"); - } - Vote vote; - vote = new Vote( - "TestVote", - target.getName(), - "127.0.0.1", - Long.toString(System.currentTimeMillis(), 10) - ); - Bukkit.getPluginManager().callEvent(new VotifierEvent(vote)); - }) - ) - .withSubcommand(new CommandAPICommand("removevote") - .withArguments(new PlayerArgument("player"), new IntegerArgument("amount")) - .executes((player, args) -> { - Player target = (Player) args.get("player"); - int amount = (int) args.get("amount"); - assert target != null && amount > 0; - plugin.getVoteStorage().removeVote(target.getUniqueId(), amount); - plugin.getMessageManager().sendMessage(player, "REMOVE_VOTE", "%player%", target.getName(), "%amount%", String.valueOf(amount)); - }) - ) - .withSubcommand(new CommandAPICommand("voteparty") - .withSubcommand(new CommandAPICommand("forcestart") - .withArguments(new BooleanArgument("reset_vote_progress")) - .executes((player, args) -> { - boolean resetVoteProgress = (boolean) args.get("reset_vote_progress"); - plugin.getVotePartyManager().forceVoteParty(resetVoteProgress); - }) - ) - .withSubcommand(new CommandAPICommand("add") - .withArguments(new IntegerArgument("amount")) - .executes((player, args) -> { - int amount = (int) args.get("amount"); - plugin.getVotePartyManager().forceAddAmount(amount); - }) - ) - .withSubcommand(new CommandAPICommand("set") - .withArguments(new IntegerArgument("amount")) - .executes((player, args) -> { - int amount = (int) args.get("amount"); - plugin.getVotePartyManager().setCurrentVoteCount(amount); - }) - ) - ) - .withSubcommand(new CommandAPICommand("streaks") - .withSubcommand(new CommandAPICommand("reset") - .withArguments(new PlayerArgument("player")) - .executes((player, args) -> { - Player target = (Player) args.get("player"); - assert target != null; - LocalDate today = LocalDate.now(); - plugin.getVoteStorage().resetStreak(target.getUniqueId(), today.toString()); - plugin.getMessageManager().sendMessage(player, "STREAK_RESET", "%player%", target.getName()); - }) - ) - .withSubcommand(new CommandAPICommand("set") - .withArguments(new PlayerArgument("player"), new IntegerArgument("streak")) - .executes((player, args) -> { - Player target = (Player) args.get("player"); - int streak = (int) args.get("streak"); - assert target != null; - plugin.getVoteStorage().setVoteStreak(target.getUniqueId(), streak); - plugin.getMessageManager().sendMessage(player, "STREAK_SET", "%player%", target.getName(), "%streak%", String.valueOf(streak)); - }) - ) - .withSubcommand(new CommandAPICommand("add") - .withArguments(new PlayerArgument("player"), new IntegerArgument("streak")) - .executes((player, args) -> { - Player target = (Player) args.get("player"); - int streak = (int) args.get("streak"); - assert target != null; - plugin.getVoteStorage().addStreak(target.getUniqueId(), streak); - plugin.getMessageManager().sendMessage(player, "STREAK_ADD", "%player%", target.getName(), "%streak%", String.valueOf(streak)); - }) - ) - ) - .withSubcommand(new CommandAPICommand("opengui") - .withArguments(new PlayerArgument("target"), new StringArgument("gui") - .replaceSuggestions(ArgumentSuggestions.strings("leaderboard", "milestones", "streaks")) - ) - .executes((player, args) -> { - Player target = (Player) args.get("target"); - String gui = (String) args.get("gui"); - assert target != null; - if (gui == null) { - player.sendMessage(Color.hex("&4&l[&c&l!&4&l] &cThe GUI type &f" + gui + " &cdoes not exist.")); - return; - } - switch (gui) { - case "leaderboard": - target.openInventory(plugin.getLeaderboardInventory().createInventory(target)); - break; - case "milestones": - if (plugin.getConfigurationManager().isModuleEnabled("Milestones")) { - target.openInventory(plugin.getMilestonesInventory().createInventory(target)); - } - break; - case "streaks": - if (plugin.getConfigurationManager().isModuleEnabled("Streaks-Menu")) { - target.openInventory(plugin.getStreaksInventory().createInventory(target)); - } - break; + target.openInventory(plugin.getStreaksInventory().createInventory(target)); } - }) - ) - .withSubcommand(new CommandAPICommand("sendvotelist") - .withArguments(new PlayerArgument("player")) - .executes((player, args) -> { - Player target = (Player) args.get("player"); - assert target != null; - - plugin.getMessageManager().sendMessage(target, "VOTE_LIST", - "%daily_votes%", String.valueOf(plugin.getVoteStorage().getPlayerVoteCount(target.getUniqueId(), "daily"))); - }) - ) - - .register(); + break; + default: + sender.sendMessage(Color.hex("&4&l[&c&l!&4&l] &cThe GUI type &f" + gui + " &cdoes not exist.")); + break; + } + }); } } diff --git a/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/PlayerCommands.java b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/PlayerCommands.java index f1c6f4b..85c803c 100644 --- a/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/PlayerCommands.java +++ b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/PlayerCommands.java @@ -1,80 +1,132 @@ package me.fergs.phantomvoting.commands; -import dev.jorel.commandapi.CommandAPICommand; import me.fergs.phantomvoting.PhantomVoting; +import me.fergs.phantomvoting.commands.impl.CommandArguments; +import me.fergs.phantomvoting.commands.impl.CommandManager; +import me.fergs.phantomvoting.commands.impl.CustomCommand; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; -public class PlayerCommands{ +import java.util.Collections; +import java.util.List; + +public class PlayerCommands { /** * Registers the player commands. * * @param plugin The plugin instance. + * @param commandManager The command manager. + */ + public void register(final PhantomVoting plugin, CommandManager commandManager) { + String baseCommand = plugin.getConfigurationManager().getConfig("config").getString("Commands.Base.Command", "vote"); + List aliases = plugin.getConfigurationManager().getConfig("config").getStringList("Commands.Base.Aliases"); + + commandManager.registerCommand( + new CustomCommand(baseCommand, "Vote command", "/" + baseCommand, aliases) + .executesPlayer((Player player, CommandArguments args) -> + plugin.getMessageManager().sendMessage(player, "VOTE_LIST", + "%daily_votes%", String.valueOf(plugin.getVoteStorage().getPlayerVoteCount(player.getUniqueId(), "daily")))) + .withSubcommand(createLeaderboardCommand(plugin)) + .withSubcommand(createMilestonesCommand(plugin)) + .withSubcommand(createStreaksCommand(plugin)) + .withSubcommand(createToggleCommand(plugin)) + ); + } + + /** + * Creates the leaderboard subcommand. + */ + private CustomCommand createLeaderboardCommand(PhantomVoting plugin) { + return new CustomCommand("leaderboard") + .executesPlayer((Player player, CommandArguments args) -> + player.openInventory(plugin.getLeaderboardInventory().createInventory(player))); + } + + /** + * Creates the milestones subcommand. */ - public void register(final PhantomVoting plugin) { - new CommandAPICommand(plugin.getConfigurationManager().getConfig("config").getString("Commands.Base.Command", "vote")) - .withAliases(plugin.getConfigurationManager().getConfig("config").getStringList("Commands.Base.Aliases").toArray(new String[0])) - .executesPlayer((player, args) -> { - plugin.getMessageManager().sendMessage(player, "VOTE_LIST", - "%daily_votes%", String.valueOf(plugin.getVoteStorage().getPlayerVoteCount(player.getUniqueId(), "daily"))); - }) - .withSubcommand(new CommandAPICommand("leaderboard") - .executesPlayer((player, args) -> { - player.openInventory(plugin.getLeaderboardInventory().createInventory(player)); - }) - ) - .withSubcommand(new CommandAPICommand("milestones") - .executesPlayer((player, args) -> { - if (!plugin.getConfigurationManager().isModuleEnabled("Milestones")) { - plugin.getMessageManager().sendMessage(player, "MODULE_DISABLED"); - return; - } - if (plugin.getConfigurationManager().getConfig("modules").getBoolean("Module-Permissions.Enabled", false)) { - if (!player.hasPermission(plugin.getConfigurationManager().getConfig("modules").getString("Module-Permissions.Modules.Milestones.Permission", "phantomvoting.milestones"))) { - plugin.getMessageManager().sendMessage(player, "NO_PERMISSION"); - return; - } - } - player.openInventory(plugin.getMilestonesInventory().createInventory(player)); - }) - ) - .withSubcommand(new CommandAPICommand("streaks") - .executesPlayer((player, args) -> { - if (!plugin.getConfigurationManager().isModuleEnabled("Streaks-Menu")) { - plugin.getMessageManager().sendMessage(player, "MODULE_DISABLED"); - return; - } - if (plugin.getConfigurationManager().getConfig("modules").getBoolean("Module-Permissions.Enabled", false)) { - if (!player.hasPermission(plugin.getConfigurationManager().getConfig("modules").getString("Module-Permissions.Modules.Streaks.Permission", "phantomvoting.streaks"))) { - plugin.getMessageManager().sendMessage(player, "NO_PERMISSION"); - return; - } + private CustomCommand createMilestonesCommand(PhantomVoting plugin) { + return new CustomCommand("milestones") + .withTabCompleter((sender, args) -> Collections.emptyList()) + .executesPlayer((Player player, CommandArguments args) -> { + if (!plugin.getConfigurationManager().isModuleEnabled("Milestones")) { + plugin.getMessageManager().sendMessage(player, "MODULE_DISABLED"); + return; + } + + if (plugin.getConfigurationManager().getConfig("modules").getBoolean("Module-Permissions.Enabled", false)) { + String permission = plugin.getConfigurationManager().getConfig("modules") + .getString("Module-Permissions.Modules.Milestones.Permission", "phantomvoting.milestones"); + if (!player.hasPermission(permission)) { + plugin.getMessageManager().sendMessage(player, "NO_PERMISSION"); + return; } - player.openInventory(plugin.getStreaksInventory().createInventory(player)); - }) - ) - .withSubcommand(new CommandAPICommand("toggle") - .withSubcommand(new CommandAPICommand("reminder") - .executesPlayer((player, args) -> { - if (!plugin.getConfigurationManager().isModuleEnabled("VoteReminder")) { - plugin.getMessageManager().sendMessage(player, "MODULE_DISABLED"); - return; - } - String permission = plugin.getConfigurationManager().getConfig("modules/vote_reminder").getString("Permission-Settings.Toggle-Permission", "phantomvoting.votereminder"); - if (!player.hasPermission(permission)) { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), plugin.getConfigurationManager().getConfig("modules/vote_reminder").getString("Permission-Settings.Set-Permission-Command", "this should be a command") - .replace("%player%", player.getName())); + } + + player.openInventory(plugin.getMilestonesInventory().createInventory(player)); + }); + } + + /** + * Creates the streaks subcommand. + */ + private CustomCommand createStreaksCommand(PhantomVoting plugin) { + return new CustomCommand("streaks") + .withTabCompleter((sender, args) -> Collections.emptyList()) + .executesPlayer((Player player, CommandArguments args) -> { + if (!plugin.getConfigurationManager().isModuleEnabled("Streaks-Menu")) { + plugin.getMessageManager().sendMessage(player, "MODULE_DISABLED"); + return; + } + + if (plugin.getConfigurationManager().getConfig("modules").getBoolean("Module-Permissions.Enabled", false)) { + String permission = plugin.getConfigurationManager().getConfig("modules") + .getString("Module-Permissions.Modules.Streaks.Permission", "phantomvoting.streaks"); + if (!player.hasPermission(permission)) { + plugin.getMessageManager().sendMessage(player, "NO_PERMISSION"); + return; + } + } + + player.openInventory(plugin.getStreaksInventory().createInventory(player)); + }); + } + + /** + * Creates the toggle command with reminder subcommand. + */ + private CustomCommand createToggleCommand(PhantomVoting plugin) { + return new CustomCommand("toggle") + .withSubcommand(createReminderToggleCommand(plugin)); + } + + /** + * Creates the reminder toggle subcommand. + */ + private CustomCommand createReminderToggleCommand(PhantomVoting plugin) { + return new CustomCommand("reminder") + .executesPlayer((Player player, CommandArguments args) -> { + if (!plugin.getConfigurationManager().isModuleEnabled("VoteReminder")) { + plugin.getMessageManager().sendMessage(player, "MODULE_DISABLED"); + return; + } - plugin.getMessageManager().sendMessage(player, "VOTE_REMINDER_TOGGLE", "%status%", "enabled"); - } - else { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), plugin.getConfigurationManager().getConfig("modules/vote_reminder").getString("Permission-Settings.Remove-Permission-Command", "this should be a command") - .replace("%player%", player.getName())); + String permission = plugin.getConfigurationManager().getConfig("modules/vote_reminder") + .getString("Permission-Settings.Toggle-Permission", "phantomvoting.votereminder"); - plugin.getMessageManager().sendMessage(player, "VOTE_REMINDER_TOGGLE", "%status%", "disabled"); - } - }) - ) - ) - .register(); + if (!player.hasPermission(permission)) { + String setCommand = plugin.getConfigurationManager().getConfig("modules/vote_reminder") + .getString("Permission-Settings.Set-Permission-Command") + .replace("%player%", player.getName()); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), setCommand); + plugin.getMessageManager().sendMessage(player, "VOTE_REMINDER_TOGGLE", "%status%", "enabled"); + } else { + String removeCommand = plugin.getConfigurationManager().getConfig("modules/vote_reminder") + .getString("Permission-Settings.Remove-Permission-Command") + .replace("%player%", player.getName()); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), removeCommand); + plugin.getMessageManager().sendMessage(player, "VOTE_REMINDER_TOGGLE", "%status%", "disabled"); + } + }); } } diff --git a/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CommandArguments.java b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CommandArguments.java new file mode 100644 index 0000000..c14b5b6 --- /dev/null +++ b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CommandArguments.java @@ -0,0 +1,127 @@ +package me.fergs.phantomvoting.commands.impl; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; + +/** + * Handles command arguments with type-safe retrieval. + */ +public class CommandArguments { + private final String[] rawArgs; + private final Map parsedArgs = new HashMap<>(); + + public CommandArguments(String[] args) { + this.rawArgs = args; + } + + /** + * Gets a raw argument by index. + * + * @param index the index + * @return the argument or null if out of bounds + */ + public String getRaw(int index) { + if (index >= 0 && index < rawArgs.length) { + return rawArgs[index]; + } + return null; + } + + /** + * Gets the raw arguments array. + * + * @return the raw arguments + */ + public String[] getRawArgs() { + return rawArgs; + } + + /** + * Gets the number of arguments. + * + * @return the argument count + */ + public int size() { + return rawArgs.length; + } + + /** + * Adds a parsed argument. + * + * @param key the argument key + * @param value the argument value + */ + public void put(String key, Object value) { + parsedArgs.put(key, value); + } + + /** + * Gets a parsed argument. + * + * @param key the argument key + * @return the argument value + */ + public Object get(String key) { + return parsedArgs.get(key); + } + + /** + * Gets a player argument by index. + * + * @param index the index + * @return the player or null if not found + */ + public Player getPlayer(int index) { + String name = getRaw(index); + if (name != null) { + return Bukkit.getPlayer(name); + } + return null; + } + + /** + * Gets an integer argument by index. + * + * @param index the index + * @return the integer or null if invalid + */ + public Integer getInt(int index) { + String value = getRaw(index); + if (value != null) { + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return null; + } + } + return null; + } + + /** + * Gets a boolean argument by index. + * + * @param index the index + * @return the boolean or null if invalid + */ + public Boolean getBoolean(int index) { + String value = getRaw(index); + if (value != null) { + return Boolean.parseBoolean(value); + } + return null; + } + + /** + * Gets a string argument by index. + * + * @param index the index + * @return the string or null if out of bounds + */ + public String getString(int index) { + return getRaw(index); + } +} + diff --git a/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CommandManager.java b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CommandManager.java new file mode 100644 index 0000000..73fc40b --- /dev/null +++ b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CommandManager.java @@ -0,0 +1,59 @@ +package me.fergs.phantomvoting.commands.impl; + +import me.fergs.phantomvoting.PhantomVoting; +import me.fergs.phantomvoting.commands.AdminCommands; +import me.fergs.phantomvoting.commands.PlayerCommands; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandMap; + +import java.lang.reflect.Field; + +/** + * Manages command registration using Bukkit's internal command system. + * Compatible with both Spigot and Paper. + */ +public class CommandManager { + private final PhantomVoting plugin; + private final CommandMap commandMap; + + public CommandManager(PhantomVoting plugin) { + this.plugin = plugin; + this.commandMap = getCommandMap(); + } + + /** + * Gets the server's CommandMap using reflection. + * Works for both Spigot (?) and Paper (?). + * + * @return the CommandMap + */ + private CommandMap getCommandMap() { + try { + Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap"); + field.setAccessible(true); + return (CommandMap) field.get(Bukkit.getServer()); + } catch (NoSuchFieldException | IllegalAccessException e) { + plugin.getLogger().severe("Failed to get CommandMap: " + e.getMessage()); + return null; + } + } + + /** + * Registers a custom command to the server's command map. + * + * @param command the command to register + */ + public void registerCommand(CustomCommand command) { + if (commandMap != null) { + commandMap.register(plugin.getName().toLowerCase(), command); + } + } + + /** + * Registers all plugin commands. + */ + public void registerCommands() { + new PlayerCommands().register(plugin, this); + new AdminCommands().register(plugin, this); + } +} diff --git a/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CustomCommand.java b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CustomCommand.java new file mode 100644 index 0000000..dbe4754 --- /dev/null +++ b/PhantomVoting/src/main/java/me/fergs/phantomvoting/commands/impl/CustomCommand.java @@ -0,0 +1,181 @@ +package me.fergs.phantomvoting.commands.impl; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * Custom command implementation that supports subcommands and arguments. + * Compatible with both Spigot and Paper. + */ +public class CustomCommand extends Command { + private CommandExecutor executor; + private PlayerCommandExecutor playerExecutor; + private TabCompleter tabCompleter; + private String permission; + private final Map subcommands = new HashMap<>(); + + public CustomCommand(@NotNull String name) { + super(name); + } + + public CustomCommand(@NotNull String name, String description, String usageMessage, List aliases) { + super(name, description, usageMessage, aliases); + } + + /** + * Sets the command executor for both players and console. + * + * @param executor the executor + * @return this command + */ + public CustomCommand executes(CommandExecutor executor) { + this.executor = executor; + return this; + } + + /** + * Sets the command executor for players only. + * + * @param executor the player executor + * @return this command + */ + public CustomCommand executesPlayer(PlayerCommandExecutor executor) { + this.playerExecutor = executor; + return this; + } + + /** + * Sets the permission required to execute this command. + * + * @param permission the permission + * @return this command + */ + public CustomCommand withPermission(String permission) { + this.permission = permission; + this.setPermission(permission); + return this; + } + + /** + * Sets the tab completer for this command. + * + * @param tabCompleter the tab completer + * @return this command + */ + public CustomCommand withTabCompleter(TabCompleter tabCompleter) { + this.tabCompleter = tabCompleter; + return this; + } + + /** + * Adds a subcommand to this command. + * + * @param subcommand the subcommand + * @return this command + */ + public CustomCommand withSubcommand(CustomCommand subcommand) { + this.subcommands.put(subcommand.getName().toLowerCase(), subcommand); + return this; + } + + @Override + public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) { + if (permission != null && !sender.hasPermission(permission)) { + return true; + } + + if (args.length > 0) { + String subcommandName = args[0].toLowerCase(); + CustomCommand subcommand = subcommands.get(subcommandName); + + if (subcommand != null) { + String[] subArgs = Arrays.copyOfRange(args, 1, args.length); + return subcommand.execute(sender, subcommandName, subArgs); + } + } + + try { + if (playerExecutor != null) { + if (!(sender instanceof Player)) { + sender.sendMessage("This command can only be executed by players."); + return true; + } + playerExecutor.execute((Player) sender, new CommandArguments(args)); + } else if (executor != null) { + executor.execute(sender, new CommandArguments(args)); + } + } catch (Exception e) { + Bukkit.getLogger().warning("An error occurred while executing command '" + getName() + "': " + e.getMessage()); + e.printStackTrace(); + } + + return true; + } + + @Override + public @NotNull List tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException { + if (tabCompleter != null) { + try { + List customCompletions = tabCompleter.complete(sender, args); + if (customCompletions != null) { + return customCompletions; + } + } catch (Exception e) { + Bukkit.getLogger().warning("An error occurred while tab-completing command '" + getName() + "': " + e.getMessage()); + e.printStackTrace(); + } + } + + List completions = new ArrayList<>(); + + if (args.length == 1) { + String partial = args[0].toLowerCase(); + for (String subcommandName : subcommands.keySet()) { + if (subcommandName.startsWith(partial)) { + CustomCommand subcommand = subcommands.get(subcommandName); + if (subcommand.permission == null || sender.hasPermission(subcommand.permission)) { + completions.add(subcommandName); + } + } + } + } else if (args.length > 1) { + String subcommandName = args[0].toLowerCase(); + CustomCommand subcommand = subcommands.get(subcommandName); + if (subcommand != null) { + String[] subArgs = Arrays.copyOfRange(args, 1, args.length); + return subcommand.tabComplete(sender, subcommandName, subArgs); + } + } + + return completions; + } + + /** + * Functional interface for command execution. + */ + @FunctionalInterface + public interface CommandExecutor { + void execute(CommandSender sender, CommandArguments args) throws Exception; + } + + /** + * Functional interface for player-only command execution. + */ + @FunctionalInterface + public interface PlayerCommandExecutor { + void execute(Player player, CommandArguments args) throws Exception; + } + + /** + * Functional interface for tab completion. + */ + @FunctionalInterface + public interface TabCompleter { + List complete(CommandSender sender, String[] args) throws Exception; + } +} diff --git a/PhantomVoting/src/main/java/me/fergs/phantomvoting/database/VoteStorage.java b/PhantomVoting/src/main/java/me/fergs/phantomvoting/database/VoteStorage.java index 6c67581..8385207 100644 --- a/PhantomVoting/src/main/java/me/fergs/phantomvoting/database/VoteStorage.java +++ b/PhantomVoting/src/main/java/me/fergs/phantomvoting/database/VoteStorage.java @@ -182,6 +182,7 @@ public void checkAndAddColumns() { public void addVote(UUID playerUUID) { String currentTimestamp = LocalDateTime.now().toString(); LocalDateTime now = LocalDateTime.now(); + LocalDate today = now.toLocalDate(); try { String selectSQL = "SELECT * FROM player_votes WHERE uuid = ?"; @@ -205,27 +206,28 @@ public void addVote(UUID playerUUID) { monthlyTimestamp = LocalDateTime.parse(rs.getString("monthly_timestamp")); yearlyTimestamp = LocalDateTime.parse(rs.getString("yearly_timestamp")); } - - if (dailyTimestamp.isBefore(now.minusDays(1))) { - resetVote("daily", playerUUID, currentTimestamp); + + LocalDate dailyDate = dailyTimestamp.toLocalDate(); + if (dailyDate.isBefore(today)) { + resetAndIncrementVote("daily", playerUUID, currentTimestamp); } else { incrementVote("daily", playerUUID); } if (weeklyTimestamp.isBefore(now.minusWeeks(1))) { - resetVote("weekly", playerUUID, currentTimestamp); + resetAndIncrementVote("weekly", playerUUID, currentTimestamp); } else { incrementVote("weekly", playerUUID); } if (monthlyTimestamp.isBefore(now.minusMonths(1))) { - resetVote("monthly", playerUUID, currentTimestamp); + resetAndIncrementVote("monthly", playerUUID, currentTimestamp); } else { incrementVote("monthly", playerUUID); } if (yearlyTimestamp.isBefore(now.minusYears(1))) { - resetVote("yearly", playerUUID, currentTimestamp); + resetAndIncrementVote("yearly", playerUUID, currentTimestamp); } else { incrementVote("yearly", playerUUID); } @@ -263,6 +265,7 @@ public void addMultipleVotes(UUID playerUUID, int voteAmount) { } LocalDateTime now = LocalDateTime.now(); + LocalDate today = now.toLocalDate(); String currentTimestamp = now.toString(); try { @@ -288,7 +291,8 @@ public void addMultipleVotes(UUID playerUUID, int voteAmount) { yearlyTimestamp = LocalDateTime.parse(rs.getString("yearly_timestamp")); } - boolean resetDaily = dailyTimestamp.isBefore(now.minusDays(1)); + LocalDate dailyDate = dailyTimestamp.toLocalDate(); + boolean resetDaily = dailyDate.isBefore(today); boolean resetWeekly = weeklyTimestamp.isBefore(now.minusWeeks(1)); boolean resetMonthly = monthlyTimestamp.isBefore(now.minusMonths(1)); boolean resetYearly = yearlyTimestamp.isBefore(now.minusYears(1)); @@ -319,13 +323,13 @@ public void addMultipleVotes(UUID playerUUID, int voteAmount) { } } /** - * Resets a specific vote period if the timestamp is expired (older than the threshold). + * Resets a specific vote period and sets the count to 1 (for the current vote). * @param period The vote period to reset (daily, weekly, monthly, yearly) * @param playerUUID UUID of the player * @param newTimestamp The new timestamp to store */ - private void resetVote(String period, UUID playerUUID, String newTimestamp) { - String updateSQL = "UPDATE player_votes SET " + period + "_count = 0, " + period + "_timestamp = ? WHERE uuid = ?"; + private void resetAndIncrementVote(String period, UUID playerUUID, String newTimestamp) { + String updateSQL = "UPDATE player_votes SET " + period + "_count = 1, " + period + "_timestamp = ? WHERE uuid = ?"; try (PreparedStatement pstmt = connection.prepareStatement(updateSQL)) { pstmt.setString(1, newTimestamp); pstmt.setString(2, playerUUID.toString()); @@ -369,11 +373,52 @@ public void removeVote(UUID playerUUID, int count) { * @return The vote count */ public int getPlayerVoteCount(UUID playerUUID, String type) { - String querySQL = "SELECT " + type + "_count FROM player_votes WHERE uuid = ?;"; + String querySQL = "SELECT * FROM player_votes WHERE uuid = ?;"; try (PreparedStatement pstmt = connection.prepareStatement(querySQL)) { pstmt.setString(1, playerUUID.toString()); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { + if ("all_time".equals(type)) { + return rs.getInt(type + "_count"); + } + + LocalDateTime now = LocalDateTime.now(); + LocalDate today = now.toLocalDate(); + + String timestampColumn = type + "_timestamp"; + String timestamp = rs.getString(timestampColumn); + if (timestamp == null) { + return 0; + } + + LocalDateTime storedTimestamp; + if (useMySQL) { + storedTimestamp = LocalDateTime.parse(timestamp, formatter); + } else { + storedTimestamp = LocalDateTime.parse(timestamp); + } + + boolean expired = false; + switch (type) { + case "daily": + LocalDate storedDate = storedTimestamp.toLocalDate(); + expired = storedDate.isBefore(today); + break; + case "weekly": + expired = storedTimestamp.isBefore(now.minusWeeks(1)); + break; + case "monthly": + expired = storedTimestamp.isBefore(now.minusMonths(1)); + break; + case "yearly": + expired = storedTimestamp.isBefore(now.minusYears(1)); + break; + } + + if (expired) { + return 0; + } + return rs.getInt(type + "_count"); } } catch (SQLException e) {