diff --git a/pom.xml b/pom.xml index dce4e05..17adb07 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.xemor Superheroes2 - 2.3.0 + 2.4.0 jar Superheroes2 diff --git a/src/main/java/me/xemor/superheroes2/Superheroes2.java b/src/main/java/me/xemor/superheroes2/Superheroes2.java index 17431b1..a56a65e 100644 --- a/src/main/java/me/xemor/superheroes2/Superheroes2.java +++ b/src/main/java/me/xemor/superheroes2/Superheroes2.java @@ -1,7 +1,6 @@ package me.xemor.superheroes2; -import me.xemor.superheroes2.commands.HeroCMD; -import me.xemor.superheroes2.commands.Reload; +import me.xemor.superheroes2.commands.HeroCommand; import me.xemor.superheroes2.commands.Reroll; import me.xemor.superheroes2.data.ConfigHandler; import me.xemor.superheroes2.data.HeroHandler; @@ -36,16 +35,13 @@ public void onEnable() { heroHandler = new HeroHandler(this, configHandler); registerSkills(); Reroll reroll = new Reroll(heroHandler, configHandler); - Reload reload = new Reload(heroHandler, configHandler); - this.getCommand("heroreload").setExecutor(reload); this.getServer().getPluginManager().registerEvents(reroll, this); this.getServer().getPluginManager().registerEvents(this, this); this.getServer().getPluginManager().registerEvents(heroHandler, this); - HeroCMD heroCMD = new HeroCMD(heroHandler, configHandler); + HeroCommand heroCommand = new HeroCommand(heroHandler, reroll); PluginCommand command = this.getCommand("hero"); - command.setExecutor(heroCMD); - command.setTabCompleter(heroCMD); - this.getCommand("reroll").setExecutor(reroll); + command.setExecutor(heroCommand); + command.setTabCompleter(heroCommand); handleMetrics(); checkForNewUpdate(); bukkitAudiences = BukkitAudiences.create(this); diff --git a/src/main/java/me/xemor/superheroes2/commands/Export.java b/src/main/java/me/xemor/superheroes2/commands/Export.java new file mode 100644 index 0000000..bea8fe3 --- /dev/null +++ b/src/main/java/me/xemor/superheroes2/commands/Export.java @@ -0,0 +1,44 @@ +package me.xemor.superheroes2.commands; + +import de.themoep.minedown.adventure.MineDown; +import me.xemor.superheroes2.Superheroes2; +import me.xemor.superheroes2.data.ConfigHandler; +import me.xemor.superheroes2.data.HeroHandler; +import net.kyori.adventure.audience.Audience; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import java.util.List; + +public class Export implements SubCommand { + + private final String exporting = ChatColor.translateAlternateColorCodes('&', "&aExporting..."); + private final String done = ChatColor.translateAlternateColorCodes('&', "&aDone!"); + private HeroHandler heroHandler; + private ConfigHandler configHandler; + + public Export(HeroHandler heroHandler, ConfigHandler configHandler) { + this.heroHandler = heroHandler; + this.configHandler = configHandler; + } + + @Override + public void onCommand(CommandSender sender, String[] args) { + if (sender.hasPermission("superheroes.export")) { + sender.sendMessage(exporting); + heroHandler.exportFiles(); + configHandler.reloadConfig(heroHandler); + sender.sendMessage(done); + } + else { + Audience audience = Superheroes2.getBukkitAudiences().sender(sender); + audience.sendMessage(MineDown.parse(configHandler.getNoPermissionMessage())); + } + } + + @Override + public List tabComplete(CommandSender sender, String[] args) { + return null; + } + +} diff --git a/src/main/java/me/xemor/superheroes2/commands/HeroCommand.java b/src/main/java/me/xemor/superheroes2/commands/HeroCommand.java new file mode 100644 index 0000000..7aa9f25 --- /dev/null +++ b/src/main/java/me/xemor/superheroes2/commands/HeroCommand.java @@ -0,0 +1,88 @@ +package me.xemor.superheroes2.commands; + +import de.themoep.minedown.adventure.MineDown; +import me.xemor.superheroes2.Superheroes2; +import me.xemor.superheroes2.data.ConfigHandler; +import me.xemor.superheroes2.data.HeroHandler; +import net.kyori.adventure.audience.Audience; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class HeroCommand implements CommandExecutor, TabExecutor { + + private HeroHandler heroHandler; + private ConfigHandler configHandler; + private HeroSelect heroSelectCommand; + private Reload reloadCommand; + private Import importCommand; + private Export exportCommand; + private Reroll reroll; + + public HeroCommand(HeroHandler heroHandler, Reroll reroll) { + this.heroHandler = heroHandler; + this.reroll = reroll; + configHandler = heroHandler.getPlugin().getConfigHandler(); + reloadCommand = new Reload(heroHandler, configHandler); + heroSelectCommand = new HeroSelect(heroHandler, configHandler); + importCommand = new Import(heroHandler, configHandler); + exportCommand = new Export(heroHandler, configHandler); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length >= 1) { + Audience audience = Superheroes2.getBukkitAudiences().sender(sender); + SubCommands commandType; + try { + commandType = SubCommands.valueOf(args[0].toUpperCase()); + } catch(IllegalArgumentException e) { + audience.sendMessage(MineDown.parse(configHandler.getInvalidCommandMessage(), "name", sender.getName())); + return true; + } + switch (commandType) { + case SELECT: heroSelectCommand.onCommand(sender, args); break; + case RELOAD: reloadCommand.onCommand(sender, args); break; + case REROLL: reroll.onCommand(sender, args); break; + case EXPORT: exportCommand.onCommand(sender, args); break; + case IMPORT: importCommand.onCommand(sender, args); break; + } + } + return true; + } + + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + List tabComplete = new ArrayList<>(); + if (args.length == 1) { + for (SubCommands subCommandEnum : SubCommands.values()) { + String subCommandStr = subCommandEnum.toString().toLowerCase(); + if (subCommandStr.startsWith(args[0].toLowerCase())) { + tabComplete.add(subCommandStr); + } + } + } + else if (args.length > 1) { + SubCommands subCommand; + try { + subCommand = SubCommands.valueOf(args[0].toUpperCase()); + switch (subCommand) { + case SELECT: tabComplete = heroSelectCommand.tabComplete(sender, args); break; + case RELOAD: tabComplete = reloadCommand.tabComplete(sender, args); break; + case REROLL: tabComplete = reroll.tabComplete(sender, args); break; + case EXPORT: tabComplete = exportCommand.tabComplete(sender, args); break; + case IMPORT: tabComplete = importCommand.tabComplete(sender, args); break; + } + } catch(IllegalArgumentException ignored) {} + } + return tabComplete; + } +} diff --git a/src/main/java/me/xemor/superheroes2/commands/HeroCMD.java b/src/main/java/me/xemor/superheroes2/commands/HeroSelect.java similarity index 75% rename from src/main/java/me/xemor/superheroes2/commands/HeroCMD.java rename to src/main/java/me/xemor/superheroes2/commands/HeroSelect.java index 30ab9bc..cd6bca4 100644 --- a/src/main/java/me/xemor/superheroes2/commands/HeroCMD.java +++ b/src/main/java/me/xemor/superheroes2/commands/HeroSelect.java @@ -9,50 +9,46 @@ import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.List; -public class HeroCMD implements CommandExecutor, TabExecutor { +public class HeroSelect implements SubCommand { private final HeroHandler heroHandler; private final ConfigHandler configHandler; - public HeroCMD(HeroHandler heroHandler, ConfigHandler configHandler) { + public HeroSelect(HeroHandler heroHandler, ConfigHandler configHandler) { this.heroHandler = heroHandler; this.configHandler = configHandler; } + //args[0] is select, args[1] is the hero name, args[2] is the player being given the new hero @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public void onCommand(CommandSender sender, String[] args) { Audience audience = Superheroes2.getBukkitAudiences().sender(sender); if (!sender.hasPermission("superheroes.hero")) { audience.sendMessage(MineDown.parse(configHandler.getNoPermissionMessage(), "player", sender.getName())); - return true; + return; } - if (args.length == 0) { + if (args.length <= 1) { if (sender instanceof Player) { Player player = (Player) sender; Superhero superhero = heroHandler.getSuperhero(player); audience.sendMessage(MineDown.parse(configHandler.getCurrentHeroMessage(), "player", player.getName(), "hero", superhero.getName())); - return true; - } - else { - return false; } + return; } - Superhero power = heroHandler.getSuperhero(args[0]); + Superhero power = heroHandler.getSuperhero(args[1]); if (power == null) { - return false; + audience.sendMessage(MineDown.parse(configHandler.getInvalidHeroMessage(), "player", sender.getName(), "hero", args[1])); + return; } if (!sender.hasPermission("superheroes.hero." + power.getName().toLowerCase())) { audience.sendMessage(MineDown.parse(configHandler.getNoPermissionMessage(), "player", sender.getName())); - return true; + return; } if (!sender.hasPermission("superheroes.hero.bypasscooldown") && sender instanceof Player) { Player senderPlayer = (Player) sender; @@ -64,14 +60,15 @@ public boolean onCommand(CommandSender sender, Command command, String label, St "currentcooldown", String.valueOf(Math.round(seconds)), "cooldown", String.valueOf(configHandler.getHeroCommandCooldown())); audience.sendMessage(message); - return true; + return; } } Player player; - if (args.length >= 2 && sender.hasPermission("superheroes.hero.others")) { - player = Bukkit.getPlayer(args[1]); + if (args.length >= 3 && sender.hasPermission("superheroes.hero.others")) { + player = Bukkit.getPlayer(args[2]); if (player == null) { - return false; + audience.sendMessage(MineDown.parse(configHandler.getInvalidPlayerMessage(), "player", sender.getName())); + return; } } else { @@ -79,7 +76,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St player = (Player) sender; } else { - return false; + return; } } heroHandler.setHero(player, power); @@ -88,16 +85,15 @@ public boolean onCommand(CommandSender sender, Command command, String label, St superheroPlayer.setHeroCommandTimestamp(System.currentTimeMillis()); heroHandler.saveSuperheroPlayer(superheroPlayer); } - return true; } @Override - public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + public List tabComplete(CommandSender sender, String[] args) { List heroesTabComplete = new ArrayList<>(); - if (args.length == 1) { - String firstArg = args[0]; + if (args.length == 2) { + String secondArg = args[1]; for (Superhero superhero : heroHandler.getNameToSuperhero().values()) { - if (superhero.getName().startsWith(firstArg) && sender.hasPermission("superheroes.hero." + superhero.getName().toLowerCase())) { + if (superhero.getName().startsWith(secondArg) && sender.hasPermission("superheroes.hero." + superhero.getName().toLowerCase())) { heroesTabComplete.add(superhero.getName()); } } diff --git a/src/main/java/me/xemor/superheroes2/commands/Import.java b/src/main/java/me/xemor/superheroes2/commands/Import.java new file mode 100644 index 0000000..345b495 --- /dev/null +++ b/src/main/java/me/xemor/superheroes2/commands/Import.java @@ -0,0 +1,43 @@ +package me.xemor.superheroes2.commands; + +import de.themoep.minedown.adventure.MineDown; +import me.xemor.superheroes2.Superheroes2; +import me.xemor.superheroes2.data.ConfigHandler; +import me.xemor.superheroes2.data.HeroHandler; +import net.kyori.adventure.audience.Audience; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import java.util.List; + +public class Import implements SubCommand { + + private final String importing = ChatColor.translateAlternateColorCodes('&', "&aImporting..."); + private final String done = ChatColor.translateAlternateColorCodes('&', "&aDone!"); + private HeroHandler heroHandler; + private ConfigHandler configHandler; + + public Import(HeroHandler heroHandler, ConfigHandler configHandler) { + this.heroHandler = heroHandler; + this.configHandler = configHandler; + } + + @Override + public void onCommand(CommandSender sender, String[] args) { + if (sender.hasPermission("superheroes.import")) { + sender.sendMessage(importing); + heroHandler.importFiles().thenAccept((ignored) -> Bukkit.getScheduler().runTask(heroHandler.getPlugin(), () -> configHandler.reloadConfig(heroHandler))); + sender.sendMessage(done); + } + else { + Audience audience = Superheroes2.getBukkitAudiences().sender(sender); + audience.sendMessage(MineDown.parse(configHandler.getNoPermissionMessage())); + } + } + + @Override + public List tabComplete(CommandSender sender, String[] args) { + return null; + } +} diff --git a/src/main/java/me/xemor/superheroes2/commands/Reload.java b/src/main/java/me/xemor/superheroes2/commands/Reload.java index 648ba85..ac973a4 100644 --- a/src/main/java/me/xemor/superheroes2/commands/Reload.java +++ b/src/main/java/me/xemor/superheroes2/commands/Reload.java @@ -3,11 +3,11 @@ import me.xemor.superheroes2.data.ConfigHandler; import me.xemor.superheroes2.data.HeroHandler; import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -public class Reload implements CommandExecutor { +import java.util.List; + +public class Reload implements SubCommand { private final String noPermission = ChatColor.translateAlternateColorCodes('&', "&4You do not have permission to use this power!"); private final String reloading = ChatColor.translateAlternateColorCodes('&', "&aReloading..."); @@ -15,14 +15,13 @@ public class Reload implements CommandExecutor { private final HeroHandler heroHandler; private final ConfigHandler configHandler; - public Reload(HeroHandler heroHandler, ConfigHandler configHandler) { this.heroHandler = heroHandler; this.configHandler = configHandler; } @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public void onCommand(CommandSender sender, String[] args) { if (sender.hasPermission("superheroes.reload")) { sender.sendMessage(reloading); configHandler.reloadConfig(heroHandler); @@ -31,6 +30,10 @@ public boolean onCommand(CommandSender sender, Command command, String label, St else { sender.sendMessage(noPermission); } - return true; + } + + @Override + public List tabComplete(CommandSender sender, String[] args) { + return null; } } diff --git a/src/main/java/me/xemor/superheroes2/commands/Reroll.java b/src/main/java/me/xemor/superheroes2/commands/Reroll.java index 61a22c0..9f98d60 100644 --- a/src/main/java/me/xemor/superheroes2/commands/Reroll.java +++ b/src/main/java/me/xemor/superheroes2/commands/Reroll.java @@ -1,13 +1,14 @@ package me.xemor.superheroes2.commands; +import de.themoep.minedown.adventure.MineDown; import me.xemor.superheroes2.CooldownHandler; +import me.xemor.superheroes2.Superheroes2; import me.xemor.superheroes2.data.ConfigHandler; import me.xemor.superheroes2.data.HeroHandler; +import net.kyori.adventure.audience.Audience; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -16,7 +17,9 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; -public class Reroll implements Listener, CommandExecutor { +import java.util.List; + +public class Reroll implements SubCommand, Listener { HeroHandler heroHandler; ConfigHandler configHandler; @@ -48,13 +51,15 @@ public void onRightClick(PlayerInteractEvent e) { } @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public void onCommand(CommandSender sender, String[] args) { + Audience audience = Superheroes2.getBukkitAudiences().sender(sender); if (sender.hasPermission("superheroes.reroll")) { Player player; - if (args.length >= 1) { - player = Bukkit.getPlayer(args[0]); + if (args.length >= 2) { + player = Bukkit.getPlayer(args[1]); if (player == null) { - return false; + audience.sendMessage(MineDown.parse(configHandler.getInvalidPlayerMessage(), "player", sender.getName())); + return; } } else { @@ -62,7 +67,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St player = (Player) sender; } else { - return false; + return; } } heroHandler.setRandomHero(player); @@ -70,6 +75,10 @@ public boolean onCommand(CommandSender sender, Command command, String label, St else { sender.sendMessage(noPermission); } - return true; + } + + @Override + public List tabComplete(CommandSender sender, String[] args) { + return null; } } diff --git a/src/main/java/me/xemor/superheroes2/commands/SubCommand.java b/src/main/java/me/xemor/superheroes2/commands/SubCommand.java new file mode 100644 index 0000000..33eb75e --- /dev/null +++ b/src/main/java/me/xemor/superheroes2/commands/SubCommand.java @@ -0,0 +1,12 @@ +package me.xemor.superheroes2.commands; + +import org.bukkit.command.CommandSender; + +import java.util.List; + +public interface SubCommand { + + void onCommand(CommandSender sender, String[] args); + List tabComplete(CommandSender sender, String[] args); + +} diff --git a/src/main/java/me/xemor/superheroes2/commands/SubCommands.java b/src/main/java/me/xemor/superheroes2/commands/SubCommands.java new file mode 100644 index 0000000..46936d3 --- /dev/null +++ b/src/main/java/me/xemor/superheroes2/commands/SubCommands.java @@ -0,0 +1,7 @@ +package me.xemor.superheroes2.commands; + +public enum SubCommands { + + SELECT, RELOAD, REROLL, IMPORT, EXPORT; + +} diff --git a/src/main/java/me/xemor/superheroes2/data/ConfigHandler.java b/src/main/java/me/xemor/superheroes2/data/ConfigHandler.java index 4b38156..b0b88d6 100644 --- a/src/main/java/me/xemor/superheroes2/data/ConfigHandler.java +++ b/src/main/java/me/xemor/superheroes2/data/ConfigHandler.java @@ -141,11 +141,12 @@ public void reloadConfig(HeroHandler heroHandler) { superheroes2.reloadConfig(); config = superheroes2.getConfig(); handleSuperpowersFolder(); + heroHandler.handlePlayerData(); loadSuperheroes(heroHandler); - heroHandler.setHeroesIntoMemory(new HashMap<>()); language = YamlConfiguration.loadConfiguration(languageFile); ItemStackData itemStackData = new ItemStackData(config.getConfigurationSection("reroll.item")); item = itemStackData.getItem(); + heroHandler.setHeroesIntoMemory(new HashMap<>()); for (Player player : Bukkit.getOnlinePlayers()) { heroHandler.loadSuperheroPlayer(player); } @@ -195,6 +196,18 @@ public String getHeroCooldownMessage() { return language.getString("Chat.heroCommandCooldown", "&l%player%, /hero is currently on cooldown. You need to wait %currentcooldown%/%cooldown% more seconds!"); } + public String getInvalidHeroMessage() { + return language.getString("Chat.invalidHeroMessage", "&l%player%, You have entered an invalid hero name!"); + } + + public String getInvalidPlayerMessage() { + return language.getString("Chat.invalidPlayerMessage", "&l%player%, You have entered an invalid player name!"); + } + + public String getInvalidCommandMessage() { + return language.getString("Chat.invalidCommandMessage", "&l%player%, You have entered an invalid subcommand name!"); + } + public long getHeroCommandCooldown() { return config.getLong("heroCommand.cooldown", 0); } diff --git a/src/main/java/me/xemor/superheroes2/data/HeroHandler.java b/src/main/java/me/xemor/superheroes2/data/HeroHandler.java index 612309e..776d675 100644 --- a/src/main/java/me/xemor/superheroes2/data/HeroHandler.java +++ b/src/main/java/me/xemor/superheroes2/data/HeroHandler.java @@ -70,15 +70,27 @@ public HeroHandler(Superheroes2 superheroes2, ConfigHandler configHandler) { this.superheroes2 = superheroes2; } + public CompletableFuture importFiles() { + YAMLStorage yamlStorage = new YAMLStorage(this); + List superheroPlayers = yamlStorage.exportSuperheroPlayers(); + return storage.importSuperheroPlayers(superheroPlayers); + } + + public void exportFiles() { + List superheroPlayers = storage.exportSuperheroPlayers(); + YAMLStorage yamlStorage = new YAMLStorage(this); + yamlStorage.importSuperheroPlayers(superheroPlayers); + } + public void handlePlayerData() { String databaseType = configHandler.getDatabaseType(); if (databaseType.equalsIgnoreCase("LEGACY")) { LegacyStorage legacy = new LegacyStorage(this); - Map values = legacy.getValues(); + List values = legacy.exportSuperheroPlayers(); File file = legacy.getCurrentDataFile(); file.renameTo(new File(superheroes2.getDataFolder(), "old_data.yml")); storage = new YAMLStorage(this); - for (SuperheroPlayer superheroPlayer: values.values()) { + for (SuperheroPlayer superheroPlayer: values) { storage.saveSuperheroPlayer(superheroPlayer); } configHandler.setDatabaseType("YAML"); @@ -184,7 +196,7 @@ public void loadSuperheroPlayer(@NotNull Player player) { } public void saveSuperheroPlayer(SuperheroPlayer superheroPlayer) { - storage.saveSuperheroPlayer(superheroPlayer); + storage.saveSuperheroPlayerAsync(superheroPlayer); } public void setRandomHero(Player player) { diff --git a/src/main/java/me/xemor/superheroes2/data/storage/LegacyStorage.java b/src/main/java/me/xemor/superheroes2/data/storage/LegacyStorage.java index 0ab931d..11c4af0 100644 --- a/src/main/java/me/xemor/superheroes2/data/storage/LegacyStorage.java +++ b/src/main/java/me/xemor/superheroes2/data/storage/LegacyStorage.java @@ -10,7 +10,8 @@ import java.io.File; import java.io.IOException; -import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -34,15 +35,21 @@ public LegacyStorage(HeroHandler heroHandler) { currentDataYAML = YamlConfiguration.loadConfiguration(currentDataFile); } - public Map getValues() { - Map map = new HashMap<>(); + @Override + public List exportSuperheroPlayers() { + List players = new ArrayList<>(); for (Map.Entry item : currentDataYAML.getValues(false).entrySet()) { if (item.getValue() instanceof String) { UUID uuid = UUID.fromString(item.getKey()); - map.put(uuid, loadSuperheroPlayer(uuid)); + players.add(loadSuperheroPlayer(uuid)); } } - return map; + return players; + } + + @Override + public CompletableFuture importSuperheroPlayers(List imports) { + return CompletableFuture.allOf(); } public File getCurrentDataFile() { @@ -54,7 +61,14 @@ public File getCurrentDataFile() { * @param superheroPlayer */ @Override - public void saveSuperheroPlayer(SuperheroPlayer superheroPlayer) { } + public void saveSuperheroPlayer(SuperheroPlayer superheroPlayer) {} + + @Override + public CompletableFuture saveSuperheroPlayerAsync(@NotNull SuperheroPlayer superheroPlayer) { + CompletableFuture completableFuture = new CompletableFuture<>(); + completableFuture.complete(null); + return completableFuture; + } @Override public SuperheroPlayer loadSuperheroPlayer(UUID uuid) { diff --git a/src/main/java/me/xemor/superheroes2/data/storage/MySQLStorage.java b/src/main/java/me/xemor/superheroes2/data/storage/MySQLStorage.java index 3b4f901..345e1c1 100644 --- a/src/main/java/me/xemor/superheroes2/data/storage/MySQLStorage.java +++ b/src/main/java/me/xemor/superheroes2/data/storage/MySQLStorage.java @@ -19,8 +19,11 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.stream.Collectors; @@ -30,6 +33,7 @@ public class MySQLStorage implements Storage { private final Superheroes2 superheroes2; private final ConfigHandler configHandler; private final MysqlDataSource dataSource; + private final ReentrantLock lock = new ReentrantLock(); public MySQLStorage(HeroHandler heroHandler) { this.heroHandler = heroHandler; @@ -40,33 +44,37 @@ public MySQLStorage(HeroHandler heroHandler) { int port = configHandler.getDatabasePort(); String user = configHandler.getDatabaseUsername(); String password = configHandler.getDatabasePassword(); - Bukkit.getLogger().warning(name); - Bukkit.getLogger().warning(host); - Bukkit.getLogger().warning(String.valueOf(port)); - Bukkit.getLogger().warning(user); - Bukkit.getLogger().warning(password); dataSource = initMySQLDataSource(name, host, port, user, password); setupTable(); } - @Override - public void saveSuperheroPlayer(@NotNull SuperheroPlayer superheroPlayer) { + public CompletableFuture saveSuperheroPlayerAsync(@NotNull SuperheroPlayer superheroPlayer) { + CompletableFuture completableFuture = new CompletableFuture<>(); Bukkit.getScheduler().runTaskAsynchronously(superheroes2, () -> { - try (Connection conn = conn(); PreparedStatement stmt = conn.prepareStatement( - "REPLACE INTO superhero_players(uuid, hero, hero_cmd_timestamp) VALUES(?, ?, ?);" - )) { - stmt.setString(1, superheroPlayer.getUUID().toString()); - stmt.setString(2, superheroPlayer.getSuperhero().getName()); - stmt.setLong(3, superheroPlayer.getHeroCommandTimestamp()); - stmt.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } + lock.lock(); + saveSuperheroPlayer(superheroPlayer); + lock.unlock(); + completableFuture.complete(null); }); + return completableFuture; + } + + public void saveSuperheroPlayer(@NotNull SuperheroPlayer superheroPlayer) { + try (Connection conn = conn(); PreparedStatement stmt = conn.prepareStatement( + "REPLACE INTO superhero_players(uuid, hero, hero_cmd_timestamp) VALUES(?, ?, ?);" + )) { + stmt.setString(1, superheroPlayer.getUUID().toString()); + stmt.setString(2, superheroPlayer.getSuperhero().getName()); + stmt.setLong(3, superheroPlayer.getHeroCommandTimestamp()); + stmt.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } } @Override public SuperheroPlayer loadSuperheroPlayer(UUID uuid) { + lock.lock(); try (Connection conn = conn(); PreparedStatement stmt = conn.prepareStatement( "SELECT * FROM superhero_players WHERE uuid = ?;" )) { @@ -85,6 +93,8 @@ public SuperheroPlayer loadSuperheroPlayer(UUID uuid) { } catch(SQLException e) { e.printStackTrace(); + } finally { + lock.unlock(); } return null; } @@ -96,6 +106,36 @@ public CompletableFuture loadSuperheroPlayerAsync(@NotNull UUID return future; } + @Override + public CompletableFuture importSuperheroPlayers(List superheroPlayers) { + CompletableFuture completableFuture = new CompletableFuture<>(); + List> futures = new ArrayList<>(); + for (SuperheroPlayer superheroPlayer : superheroPlayers) { + futures.add(saveSuperheroPlayerAsync(superheroPlayer)); + } + return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + } + + @Override + public List exportSuperheroPlayers() { + List players = new ArrayList<>(); + try (Connection conn = conn(); PreparedStatement stmt = conn.prepareStatement( + "SELECT * FROM superhero_players;" + )) { + ResultSet resultSet = stmt.executeQuery(); + while (resultSet.next()) { + Superhero superhero = heroHandler.getSuperhero(resultSet.getString(2)); + if (superhero == null) { + superhero = heroHandler.getNoPower(); + } + players.add(new SuperheroPlayer(UUID.fromString(resultSet.getString(1)), superhero, resultSet.getLong(3))); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return players; + } + private MysqlDataSource initMySQLDataSource(String dbName, String host, int port, String user, String password) { MysqlDataSource dataSource = new MysqlConnectionPoolDataSource(); dataSource.setDatabaseName(dbName); @@ -103,11 +143,6 @@ private MysqlDataSource initMySQLDataSource(String dbName, String host, int port dataSource.setPortNumber(port); dataSource.setUser(user); dataSource.setPassword(password); - Bukkit.getLogger().warning(dataSource.getDatabaseName()); - Bukkit.getLogger().warning(dataSource.getServerName()); - Bukkit.getLogger().warning(String.valueOf(dataSource.getPortNumber())); - Bukkit.getLogger().warning(dataSource.getUser()); - Bukkit.getLogger().warning(dataSource.getPassword()); testDataSource(dataSource); return dataSource; } diff --git a/src/main/java/me/xemor/superheroes2/data/storage/Storage.java b/src/main/java/me/xemor/superheroes2/data/storage/Storage.java index b643711..712a92d 100644 --- a/src/main/java/me/xemor/superheroes2/data/storage/Storage.java +++ b/src/main/java/me/xemor/superheroes2/data/storage/Storage.java @@ -4,16 +4,18 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; public interface Storage { void saveSuperheroPlayer(@NotNull SuperheroPlayer superheroPlayer); - + CompletableFuture saveSuperheroPlayerAsync(@NotNull SuperheroPlayer superheroPlayer); @Nullable SuperheroPlayer loadSuperheroPlayer(@NotNull UUID uuid); - CompletableFuture loadSuperheroPlayerAsync(@NotNull UUID uuid); + CompletableFuture importSuperheroPlayers(List superheroPlayers); + List exportSuperheroPlayers(); } diff --git a/src/main/java/me/xemor/superheroes2/data/storage/YAMLStorage.java b/src/main/java/me/xemor/superheroes2/data/storage/YAMLStorage.java index 0ffdbf1..6c7d591 100644 --- a/src/main/java/me/xemor/superheroes2/data/storage/YAMLStorage.java +++ b/src/main/java/me/xemor/superheroes2/data/storage/YAMLStorage.java @@ -11,8 +11,12 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.locks.ReentrantLock; public class YAMLStorage implements Storage { @@ -20,6 +24,7 @@ public class YAMLStorage implements Storage { private final YamlConfiguration currentDataYAML; private File currentDataFile; private HeroHandler heroHandler; + private ReentrantLock yamlLock = new ReentrantLock(); public YAMLStorage(HeroHandler heroHandler) { this.superheroes2 = heroHandler.getPlugin(); @@ -46,32 +51,66 @@ public void saveSuperheroPlayer(SuperheroPlayer superheroPlayer) { section.set("hero", superheroPlayer.getSuperhero().getName()); section.set("hero_cmd_timestamp", superheroPlayer.getHeroCommandTimestamp()); currentDataYAML.set(String.valueOf(superheroPlayer.getUUID()), section); + try { + currentDataYAML.save(currentDataFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public CompletableFuture saveSuperheroPlayerAsync(@NotNull SuperheroPlayer superheroPlayer) { + CompletableFuture completableFuture = new CompletableFuture<>(); Bukkit.getScheduler().runTaskAsynchronously(superheroes2, () -> { - synchronized (currentDataYAML) { - try { - currentDataYAML.save(currentDataFile); - } catch (IOException e) { - e.printStackTrace(); - } - } + yamlLock.lock(); + saveSuperheroPlayer(superheroPlayer); + yamlLock.unlock(); + completableFuture.complete(null); }); + return completableFuture; } @Override public SuperheroPlayer loadSuperheroPlayer(UUID uuid) { + yamlLock.lock(); ConfigurationSection section = getSection(uuid); if (section == null) { return null; } Superhero superhero = heroHandler.getSuperhero(section.getString("hero", "NOPOWER")); long heroCommandTimestamp = section.getLong("hero_cmd_timestamp", 0); + yamlLock.unlock(); return new SuperheroPlayer(uuid, superhero, heroCommandTimestamp); } @Override public CompletableFuture loadSuperheroPlayerAsync(@NotNull UUID uuid) { CompletableFuture future = new CompletableFuture<>(); - Bukkit.getScheduler().runTaskAsynchronously(superheroes2, () -> future.complete(loadSuperheroPlayer(uuid))); + Bukkit.getScheduler().runTaskAsynchronously(superheroes2, () -> { + future.complete(loadSuperheroPlayer(uuid)); + }); return future; } + + @Override + public CompletableFuture importSuperheroPlayers(List superheroPlayers) { + currentDataFile.renameTo(new File(superheroes2.getDataFolder(), "old_data.yml")); + currentDataFile = new File(superheroes2.getDataFolder(), "data.yml"); + for (SuperheroPlayer superheroPlayer : superheroPlayers) { + saveSuperheroPlayer(superheroPlayer); + } + return CompletableFuture.allOf(); + } + + @Override + public List exportSuperheroPlayers() { + List list = new ArrayList<>(); + for (Map.Entry item : currentDataYAML.getValues(false).entrySet()) { + if (item.getValue() instanceof ConfigurationSection) { + UUID uuid = UUID.fromString(item.getKey()); + list.add(loadSuperheroPlayer(uuid)); + } + } + return list; + } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 273b7b9..dea7678 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,10 @@ database: type: YAML + host: "this needs filling with your host name if using mysql" + port: 3306 + name: "this needs filling with the database name if using mysql" + username: "this needs filling with the username of the account being used to connect to mysql if using mysql" + password: "this needs filling with the password being used to connect to mysql if using mysql" reroll: item: type: DIAMOND_BLOCK diff --git a/src/main/resources/dbsetup.sql b/src/main/resources/dbsetup.sql index 715796e..d6837e0 100644 --- a/src/main/resources/dbsetup.sql +++ b/src/main/resources/dbsetup.sql @@ -2,5 +2,6 @@ CREATE TABLE IF NOT EXISTS superhero_players ( uuid CHAR(36) NOT NULL, hero TEXT NOT NULL, - hero_cmd_timestamp BIGINT NOT NULL + hero_cmd_timestamp BIGINT NOT NULL, + PRIMARY KEY (uuid) ); \ No newline at end of file diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml index b91629a..a18879e 100644 --- a/src/main/resources/language.yml +++ b/src/main/resources/language.yml @@ -2,4 +2,7 @@ Chat: gainedHero: "&l%player% has gained the power of %hero%" noPermission: "&4You do not have permission to use this power!" currentHero: "&l%player%, you are currently %hero%" - heroCommandCooldown: "&l%player%, /hero is currently on cooldown. You need to wait %currentcooldown%/%cooldown% more seconds!" \ No newline at end of file + heroCommandCooldown: "&l%player%, /hero is currently on cooldown. You need to wait %currentcooldown%/%cooldown% more seconds!" + invalidHeroMessage: "&l%player%, You have entered an invalid hero name!" + invalidPlayerName: "&l%player%, You have entered an invalid player name!" + invalidCommandMessage: "&l%player%, You have entered an invalid subcommand name!" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1abe148..069dc69 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,15 +5,9 @@ api-version: 1.16 authors: [Xemor_] description: Adds superheroes to your world - these can be customized completely and are extremely modular. commands: - reroll: - description: Allows you to reroll someone's power - usage: /reroll hero: - description: Allows you to set your power + description: The root command of all of the commands within Superheroes2 usage: /hero - heroreload: - description: Allows you to reload the plugin - usage: /heroreload permissions: superheroes.hero: description: Allows them to use /hero