From 1c3b8523cc1f6c292a757c0a9b88cad13d6512e2 Mon Sep 17 00:00:00 2001 From: lowercasebtw Date: Mon, 12 Aug 2024 06:49:41 -0400 Subject: [PATCH] Switch to CommandAPI & Add auto-complete for songs --- build.gradle | 10 +- gradle.properties | 1 + gradle/wrapper/gradle-wrapper.properties | 3 +- .../Navoei/customdiscsplugin/CustomDiscs.java | 307 +++++++++--------- .../command/CommandManager.java | 77 ----- .../command/CustomDiscCommand.java | 44 +++ .../customdiscsplugin/command/SubCommand.java | 15 - .../command/SubCommands/CreateCommand.java | 178 ---------- .../command/SubCommands/CreateSubCommand.java | 132 ++++++++ .../command/SubCommands/DownloadCommand.java | 113 ------- .../SubCommands/DownloadSubCommand.java | 101 ++++++ .../customdiscsplugin/language/Lang.java | 1 - 12 files changed, 447 insertions(+), 535 deletions(-) delete mode 100644 src/main/java/me/Navoei/customdiscsplugin/command/CommandManager.java create mode 100644 src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java delete mode 100644 src/main/java/me/Navoei/customdiscsplugin/command/SubCommand.java delete mode 100644 src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateCommand.java create mode 100644 src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java delete mode 100644 src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadCommand.java create mode 100644 src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java diff --git a/build.gradle b/build.gradle index cb1c39a..bebcde2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id "com.github.johnrengelman.shadow" version "7.1.0" + id 'io.github.goooler.shadow' version '8.1.7' } sourceCompatibility = JavaLanguageVersion.of(java_version as int) @@ -38,6 +38,7 @@ dependencies { // Use this dependency if you don't want to compile bukkit implementation "io.papermc.paper:paper-api:${bukkit_version}" implementation "de.maxhenkel.voicechat:voicechat-api:${voicechat_api_version}" + shadow "dev.jorel:commandapi-bukkit-shade:${command_api_version}" compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "5.1.0"; @@ -55,12 +56,17 @@ repositories { url = uri("https://papermc.io/repo/repository/maven-public/") } maven { url "https://repo.dmulloy2.net/repository/public/" } + maven { url = "https://repo.codemc.org/repository/maven-public/" } mavenLocal() } shadowJar { configurations = [project.configurations.shadow] - classifier 'shadow-dev' + archiveClassifier.set("shadow-dev") + //relocate 'javazoom', "me.navoei.${mod_id}.javazoom" //relocate 'org.tritonus', "me.navoei.${mod_id}.tritonus" + + // By documentation, it was recommented to relocate to not cause issues with other plugins that shade CommandAPI + relocate("dev.jorel.commandapi", "me.navoei.${mod_id}.commandapi") } diff --git a/gradle.properties b/gradle.properties index a0ac45f..a2668ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,6 +10,7 @@ mod_id=customdiscsplugin # Target an older API to make it compatible with older versions of Simple Voice Chat voicechat_api_version=2.5.0 +command_api_version=9.5.2 plugin_version=3.0 maven_group=me.Navoei.customdiscsplugin diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e750102..aeef431 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Sun Aug 11 17:52:06 EDT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java b/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java index 5ad7ec8..6fca3fe 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java +++ b/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java @@ -8,10 +8,10 @@ import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; import de.maxhenkel.voicechat.api.BukkitVoicechatService; -import me.Navoei.customdiscsplugin.command.CommandManager; +import dev.jorel.commandapi.CommandAPI; +import dev.jorel.commandapi.CommandAPIBukkitConfig; +import me.Navoei.customdiscsplugin.command.CustomDiscCommand; import me.Navoei.customdiscsplugin.event.JukeBox; -import java.util.logging.Logger; - import me.Navoei.customdiscsplugin.language.Lang; import org.bukkit.NamespacedKey; import org.bukkit.block.Jukebox; @@ -23,151 +23,162 @@ import javax.annotation.Nullable; import java.io.*; import java.util.Objects; import java.util.logging.Level; +import java.util.logging.Logger; public final class CustomDiscs extends JavaPlugin { - static CustomDiscs instance; - - @Nullable - private VoicePlugin voicechatPlugin; - private Logger log; - public static YamlConfiguration LANG; - public static File LANG_FILE; - public float musicDiscDistance; - public float musicDiscVolume; - - @Override - public void onEnable() { - - CustomDiscs.instance = this; - log = getLogger(); - - BukkitVoicechatService service = getServer().getServicesManager().load(BukkitVoicechatService.class); - - this.saveDefaultConfig(); - loadLang(); - - File musicData = new File(this.getDataFolder(), "musicdata"); - if (!(musicData.exists())) { - musicData.mkdirs(); - } - - if (service != null) { - voicechatPlugin = new VoicePlugin(); - service.registerPlugin(voicechatPlugin); - log.info("Successfully registered CustomDiscs plugin"); - } else { - log.info("Failed to register CustomDiscs plugin"); - } - - getServer().getPluginManager().registerEvents(new JukeBox(), this); - getServer().getPluginManager().registerEvents(new HopperManager(), this); - getCommand("customdisc").setExecutor(new CommandManager()); - - musicDiscDistance = getConfig().getInt("music-disc-distance"); - musicDiscVolume = Float.parseFloat(Objects.requireNonNull(getConfig().getString("music-disc-volume"))); - - ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); - - protocolManager.addPacketListener(new PacketAdapter(this, ListenerPriority.NORMAL, PacketType.Play.Server.WORLD_EVENT) { - @Override - public void onPacketSending(PacketEvent event) { - PacketContainer packet = event.getPacket(); - - if (packet.getIntegers().read(0).toString().equals("1010")) { - Jukebox jukebox = (Jukebox) packet.getBlockPositionModifier().read(0).toLocation(event.getPlayer().getWorld()).getBlock().getState(); - - if (!jukebox.getRecord().hasItemMeta()) return; - - if (jukebox.getRecord().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(CustomDiscs.getInstance(), "customdisc"), PersistentDataType.STRING)) { - jukebox.stopPlaying(); - event.setCancelled(true); - } - - //Spawn particles if there isnt any music playing at this location. - ParticleManager.start(jukebox); - } - } - }); - - } - - @Override - public void onDisable() { - if (voicechatPlugin != null) { - getServer().getServicesManager().unregister(voicechatPlugin); - log.info("Successfully unregistered CustomDiscs plugin"); - } - } - - public static CustomDiscs getInstance() { - return instance; - } - - /** - * Load the lang.yml file. - * @return The lang.yml config. - */ - public void loadLang() { - File lang = new File(getDataFolder(), "lang.yml"); - if (!lang.exists()) { - try { - getDataFolder().mkdir(); - lang.createNewFile(); - InputStream defConfigStream = this.getResource("lang.yml"); - if (defConfigStream != null) { - copyInputStreamToFile(defConfigStream, lang); - YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(lang); - defConfig.save(lang); - Lang.setFile(defConfig); - } - } catch(IOException e) { - e.printStackTrace(); // So they notice - log.severe("Failed to create lang.yml for MyHomes."); - log.severe("Now disabling..."); - this.setEnabled(false); // Without it loaded, we can't send them messages - } - } - YamlConfiguration conf = YamlConfiguration.loadConfiguration(lang); - for(Lang item:Lang.values()) { - if (conf.getString(item.getPath()) == null) { - conf.set(item.getPath(), item.getDefault()); - } - } - Lang.setFile(conf); - LANG = conf; - LANG_FILE = lang; - try { - conf.save(getLangFile()); - } catch(IOException e) { - log.log(Level.WARNING, "Failed to save lang.yml for MyHomes"); - log.log(Level.WARNING, "Now disabling..."); - e.printStackTrace(); - } - } - - /** - * Gets the lang.yml config. - * @return The lang.yml config. - */ - public YamlConfiguration getLang() { - return LANG; - } - - /** - * Get the lang.yml file. - * @return The lang.yml file. - */ - public File getLangFile() { - return LANG_FILE; - } - - public static void copyInputStreamToFile(InputStream input, File file) { - - try (OutputStream output = new FileOutputStream(file)) { - input.transferTo(output); - } catch (IOException ioException) { - ioException.printStackTrace(); - } - - } + static CustomDiscs instance; + + @Nullable + private VoicePlugin voicechatPlugin; + private Logger log; + public static YamlConfiguration LANG; + public static File LANG_FILE; + public float musicDiscDistance; + public float musicDiscVolume; + + @Override + public void onLoad() { + CustomDiscs.instance = this; + CommandAPI.onLoad(new CommandAPIBukkitConfig(this).verboseOutput(true)); + new CustomDiscCommand(this).register("customdiscs"); + } + + @Override + public void onEnable() { + log = getLogger(); + + CommandAPI.onEnable(); + + BukkitVoicechatService service = getServer().getServicesManager().load(BukkitVoicechatService.class); + + this.saveDefaultConfig(); + loadLang(); + + File musicData = new File(this.getDataFolder(), "musicdata"); + if (!(musicData.exists())) { + musicData.mkdirs(); + } + + if (service != null) { + voicechatPlugin = new VoicePlugin(); + service.registerPlugin(voicechatPlugin); + log.info("Successfully registered CustomDiscs plugin"); + } else { + log.info("Failed to register CustomDiscs plugin"); + } + + getServer().getPluginManager().registerEvents(new JukeBox(), this); + getServer().getPluginManager().registerEvents(new HopperManager(), this); + + musicDiscDistance = getConfig().getInt("music-disc-distance"); + musicDiscVolume = Float.parseFloat(Objects.requireNonNull(getConfig().getString("music-disc-volume"))); + + ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); + + protocolManager.addPacketListener(new PacketAdapter(this, ListenerPriority.NORMAL, PacketType.Play.Server.WORLD_EVENT) { + @Override + public void onPacketSending(PacketEvent event) { + PacketContainer packet = event.getPacket(); + + if (packet.getIntegers().read(0).toString().equals("1010")) { + Jukebox jukebox = (Jukebox) packet.getBlockPositionModifier().read(0).toLocation(event.getPlayer().getWorld()).getBlock().getState(); + + if (!jukebox.getRecord().hasItemMeta()) return; + + if (jukebox.getRecord().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(CustomDiscs.getInstance(), "customdisc"), PersistentDataType.STRING)) { + jukebox.stopPlaying(); + event.setCancelled(true); + } + + //Spawn particles if there isnt any music playing at this location. + ParticleManager.start(jukebox); + } + } + }); + + } + + @Override + public void onDisable() { + CommandAPI.onDisable(); + if (voicechatPlugin != null) { + getServer().getServicesManager().unregister(voicechatPlugin); + log.info("Successfully unregistered CustomDiscs plugin"); + } + } + + public static CustomDiscs getInstance() { + return instance; + } + + /** + * Load the lang.yml file. + * + * @return The lang.yml config. + */ + public void loadLang() { + File lang = new File(getDataFolder(), "lang.yml"); + if (!lang.exists()) { + try { + getDataFolder().mkdir(); + lang.createNewFile(); + InputStream defConfigStream = this.getResource("lang.yml"); + if (defConfigStream != null) { + copyInputStreamToFile(defConfigStream, lang); + YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(lang); + defConfig.save(lang); + Lang.setFile(defConfig); + } + } catch (IOException e) { + e.printStackTrace(); // So they notice + log.severe("Failed to create lang.yml for MyHomes."); + log.severe("Now disabling..."); + this.setEnabled(false); // Without it loaded, we can't send them messages + } + } + YamlConfiguration conf = YamlConfiguration.loadConfiguration(lang); + for (Lang item : Lang.values()) { + if (conf.getString(item.getPath()) == null) { + conf.set(item.getPath(), item.getDefault()); + } + } + Lang.setFile(conf); + LANG = conf; + LANG_FILE = lang; + try { + conf.save(getLangFile()); + } catch (IOException e) { + log.log(Level.WARNING, "Failed to save lang.yml for MyHomes"); + log.log(Level.WARNING, "Now disabling..."); + e.printStackTrace(); + } + } + + /** + * Gets the lang.yml config. + * + * @return The lang.yml config. + */ + public YamlConfiguration getLang() { + return LANG; + } + + /** + * Get the lang.yml file. + * + * @return The lang.yml file. + */ + public File getLangFile() { + return LANG_FILE; + } + + public static void copyInputStreamToFile(InputStream input, File file) { + + try (OutputStream output = new FileOutputStream(file)) { + input.transferTo(output); + } catch (IOException ioException) { + ioException.printStackTrace(); + } + + } } diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/CommandManager.java b/src/main/java/me/Navoei/customdiscsplugin/command/CommandManager.java deleted file mode 100644 index 25fd962..0000000 --- a/src/main/java/me/Navoei/customdiscsplugin/command/CommandManager.java +++ /dev/null @@ -1,77 +0,0 @@ -package me.Navoei.customdiscsplugin.command; - -import me.Navoei.customdiscsplugin.CustomDiscs; -import me.Navoei.customdiscsplugin.command.SubCommands.CreateCommand; -import me.Navoei.customdiscsplugin.command.SubCommands.DownloadCommand; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; - -public class CommandManager implements CommandExecutor, TabCompleter { - - private final ArrayList subCommands = new ArrayList<>(); - - public CommandManager() { - subCommands.add(new CreateCommand()); - subCommands.add(new DownloadCommand()); - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - - if (!(sender instanceof Player)) { - sender.sendMessage(ChatColor.RED + "Only players can use this command!"); - return true; - } - - Player player = (Player) sender; - - if (args.length > 0) { - for (int i = 0; i < getSubCommands().size(); i++) { - if (args[0].equalsIgnoreCase(getSubCommands().get(i).getName())) { - getSubCommands().get(i).perform(player, args); - } - } - } else { - - FileConfiguration config = CustomDiscs.getInstance().getConfig(); - List messagesList = config.getStringList("help"); - for (String s : messagesList) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(s); - player.sendMessage(textComponent); - } - - return true; - } - - return true; - } - - public ArrayList getSubCommands() { - return subCommands; - } - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - - if (args.length == 1) { - List arguments = new ArrayList<>(); - for (int i = 0; i < getSubCommands().size(); i++) { - arguments.add(getSubCommands().get(i).getName()); - } - return arguments; - } - - return null; - } -} diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java new file mode 100644 index 0000000..dbbdf7f --- /dev/null +++ b/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java @@ -0,0 +1,44 @@ +package me.Navoei.customdiscsplugin.command; + +import dev.jorel.commandapi.CommandAPICommand; +import dev.jorel.commandapi.executors.CommandArguments; +import me.Navoei.customdiscsplugin.CustomDiscs; +import me.Navoei.customdiscsplugin.command.SubCommands.CreateSubCommand; +import me.Navoei.customdiscsplugin.command.SubCommands.DownloadSubCommand; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.ChatColor; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; + +public class CustomDiscCommand extends CommandAPICommand { + private final CustomDiscs plugin; + + public CustomDiscCommand(CustomDiscs plugin) { + super("customdisc"); + this.plugin = plugin; + + this.withAliases("cd"); + this.withFullDescription("The custom discs command."); + + this.withSubcommand(new CreateSubCommand(plugin)); + this.withSubcommand(new DownloadSubCommand(plugin)); + + this.executesPlayer(this::onCommandPlayer); + this.executesConsole(this::onCommandConsole); + } + + private int onCommandPlayer(Player player, CommandArguments arguments) { + FileConfiguration config = this.plugin.getConfig(); + for (String message : config.getStringList("help")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(message)); + } + + return 1; + } + + private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { + executor.sendMessage(ChatColor.RED + "Only players can use this command!"); + return 1; + } +} diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommand.java deleted file mode 100644 index 87c96c8..0000000 --- a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommand.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.Navoei.customdiscsplugin.command; - -import org.bukkit.entity.Player; - -public abstract class SubCommand { - - public abstract String getName(); - - public abstract String getDescription(); - - public abstract String getSyntax(); - - public abstract void perform(Player player, String[] args); - -} diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateCommand.java deleted file mode 100644 index 69c3d2b..0000000 --- a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateCommand.java +++ /dev/null @@ -1,178 +0,0 @@ -package me.Navoei.customdiscsplugin.command.SubCommands; - -import me.Navoei.customdiscsplugin.CustomDiscs; -import me.Navoei.customdiscsplugin.command.SubCommand; -import me.Navoei.customdiscsplugin.language.Lang; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.components.JukeboxPlayableComponent; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -public class CreateCommand extends SubCommand { - - @Override - public String getName() { - return "create"; - } - - @Override - public String getDescription() { - return ChatColor.GRAY + "Creates a custom music disc."; - } - - @Override - public String getSyntax() { - return "/customdisc create \"Custom Lore\""; - } - - @Override - public void perform(Player player, String[] args) { - if (isMusicDisc(player)) { - if (args.length >= 3) { - - if (!player.hasPermission("customdiscs.create")) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString()); - player.sendMessage(textComponent); - return; - } - - // /cd create test.mp3 "test" - // [0] [1] [2] - //Find file, if file not there then say "file not there" - String song_name = ""; - String filename = args[1]; - if (filename.contains("../")) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FILENAME.toString()); - player.sendMessage(textComponent); - return; - } - - if (customName(readQuotes(args)).equalsIgnoreCase("")) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_DISC_NAME_PROVIDED.toString()); - player.sendMessage(textComponent); - return; - } - - File getDirectory = new File(CustomDiscs.getInstance().getDataFolder(), "musicdata"); - File songFile = new File(getDirectory.getPath(), filename); - if (songFile.exists()) { - if (getFileExtension(filename).equals("wav") || getFileExtension(filename).equals("mp3") || getFileExtension(filename).equals("flac")) { - song_name = args[1]; - } else { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FORMAT.toString()); - player.sendMessage(textComponent); - return; - } - } else { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.FILE_NOT_FOUND.toString()); - player.sendMessage(textComponent); - return; - } - - //Sets the lore of the item to the quotes from the command. - ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand()); - ItemMeta meta = disc.getItemMeta(); - @Nullable List itemLore = new ArrayList<>(); - final TextComponent customLoreSong = Component.text() - .decoration(TextDecoration.ITALIC, false) - .content(customName(readQuotes(args))) - .color(NamedTextColor.GRAY) - .build(); - itemLore.add(customLoreSong); - meta.lore(itemLore); - JukeboxPlayableComponent jpc = meta.getJukeboxPlayable(); - jpc.setShowInTooltip(false); - meta.setJukeboxPlayable(jpc); - - PersistentDataContainer data = meta.getPersistentDataContainer(); - data.set(new NamespacedKey(CustomDiscs.getInstance(), "customdisc"), PersistentDataType.STRING, filename); - - player.getInventory().getItemInMainHand().setItemMeta(meta); - - Component textComponentFileName = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_FILENAME.toString().replace("%filename%", song_name)); - Component textComponentCustomName = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_NAME.toString().replace("%custom_name%", customName(readQuotes(args)))); - player.sendMessage(textComponentFileName); - player.sendMessage(textComponentCustomName); - } else { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_ARGUMENTS.toString().replace("%command_syntax", getSyntax())); - player.sendMessage(textComponent); - } - } else { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_DISC.toString()); - player.sendMessage(textComponent); - } - } - - private String getFileExtension(String s) { - int index = s.lastIndexOf("."); - if (index > 0) { - return s.substring(index + 1); - } else { - return ""; - } - } - - private ArrayList readQuotes(String[] args) { - ArrayList quotes = new ArrayList<>(); - String temp = ""; - boolean inQuotes = false; - - for (String s : args) { - if (s.startsWith("\"") && s.endsWith("\"")) { - temp += s.substring(1, s.length()-1); - quotes.add(temp); - } else if (s.startsWith("\"")) { - temp += s.substring(1); - quotes.add(temp); - inQuotes = true; - } else if (s.endsWith("\"")) { - temp += s.substring(0, s.length()-1); - quotes.add(temp); - inQuotes = false; - } else if (inQuotes) { - temp += s; - quotes.add(temp); - } - temp = ""; - } - - return quotes; - } - - private String customName(ArrayList q) { - - StringBuffer sb = new StringBuffer(); - - for (String s : q) { - sb.append(s); - sb.append(" "); - } - - if (sb.isEmpty()) { - return sb.toString(); - } else { - return sb.toString().substring(0, sb.length()-1); - } - } - - private boolean isMusicDisc(Player p) { - return p.getInventory().getItemInMainHand().getType().toString().contains("MUSIC_DISC"); - } - -} diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java new file mode 100644 index 0000000..ab9a2c9 --- /dev/null +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java @@ -0,0 +1,132 @@ +package me.Navoei.customdiscsplugin.command.SubCommands; + +import dev.jorel.commandapi.CommandAPICommand; +import dev.jorel.commandapi.arguments.ArgumentSuggestions; +import dev.jorel.commandapi.arguments.StringArgument; +import dev.jorel.commandapi.arguments.TextArgument; +import dev.jorel.commandapi.executors.CommandArguments; +import me.Navoei.customdiscsplugin.CustomDiscs; +import me.Navoei.customdiscsplugin.language.Lang; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.ChatColor; +import org.bukkit.NamespacedKey; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.components.JukeboxPlayableComponent; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import javax.annotation.Nullable; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public class CreateSubCommand extends CommandAPICommand { + private final CustomDiscs plugin; + + public CreateSubCommand(CustomDiscs plugin) { + super("create"); + this.plugin = plugin; + + this.withFullDescription(ChatColor.GRAY + "Creates a custom music disc."); + this.withUsage("/customdisc create \"Custom Lore\""); + + this.withArguments(new StringArgument("filename").replaceSuggestions(ArgumentSuggestions.stringCollection((sender) -> { + File musicDataFolder = new File(this.plugin.getDataFolder(), "musicdata"); + if (!musicDataFolder.isDirectory()) { + return List.of(); + } + + File[] files = musicDataFolder.listFiles(); + if (files == null) { + return List.of(); + } + + return Arrays.stream(files).filter(file -> !file.isDirectory()).map(File::getName).toList(); + }))); + + this.withArguments(new TextArgument("song_name")); + + this.executesPlayer(this::onCommandPlayer); + this.executesConsole(this::onCommandConsole); + } + + private int onCommandPlayer(Player player, CommandArguments arguments) { + if (!isMusicDisc(player)) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_DISC.toString())); + return 1; + } + + if (!player.hasPermission("customdiscs.create")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString())); + return 1; + } + + // Find file, if file not there then say "file not there" + String filename = Objects.requireNonNull(arguments.getByClass("filename", String.class)); + if (filename.contains("../")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FILENAME.toString())); + return 1; + } + + File getDirectory = new File(this.plugin.getDataFolder(), "musicdata"); + File songFile = new File(getDirectory.getPath(), filename); + if (songFile.exists()) { + if (!getFileExtension(filename).equals("wav") && !getFileExtension(filename).equals("mp3") && !getFileExtension(filename).equals("flac")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FORMAT.toString())); + return 1; + } + } else { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.FILE_NOT_FOUND.toString())); + return 1; + } + + String song_name = Objects.requireNonNull(arguments.getByClass("song_name", String.class)); + + // Sets the lore of the item to the quotes from the command. + ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand()); + ItemMeta meta = disc.getItemMeta(); + @Nullable List itemLore = new ArrayList<>(); + final TextComponent customLoreSong = Component.text().decoration(TextDecoration.ITALIC, false).content(song_name).color(NamedTextColor.GRAY).build(); + itemLore.add(customLoreSong); + meta.lore(itemLore); + JukeboxPlayableComponent jpc = meta.getJukeboxPlayable(); + jpc.setShowInTooltip(false); + meta.setJukeboxPlayable(jpc); + + PersistentDataContainer data = meta.getPersistentDataContainer(); + data.set(new NamespacedKey(this.plugin, "customdisc"), PersistentDataType.STRING, filename); + + player.getInventory().getItemInMainHand().setItemMeta(meta); + + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_FILENAME.toString().replace("%filename%", filename))); + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_NAME.toString().replace("%custom_name%", song_name))); + return 1; + } + + private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { + executor.sendMessage(ChatColor.RED + "Only players can use this command!"); + return 1; + } + + private String getFileExtension(String s) { + int index = s.lastIndexOf("."); + if (index > 0) { + return s.substring(index + 1); + } else { + return ""; + } + } + + private boolean isMusicDisc(Player p) { + return p.getInventory().getItemInMainHand().getType().toString().contains("MUSIC_DISC"); + } +} diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadCommand.java deleted file mode 100644 index 0ab64f9..0000000 --- a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadCommand.java +++ /dev/null @@ -1,113 +0,0 @@ -package me.Navoei.customdiscsplugin.command.SubCommands; - -import me.Navoei.customdiscsplugin.CustomDiscs; -import me.Navoei.customdiscsplugin.command.SubCommand; -import me.Navoei.customdiscsplugin.language.Lang; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.codehaus.plexus.util.FileUtils; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.net.URLConnection; -import java.nio.file.Path; - -public class DownloadCommand extends SubCommand { - - CustomDiscs customDiscs = CustomDiscs.getInstance(); - - @Override - public String getName() { - return "download"; - } - - @Override - public String getDescription() { - return ChatColor.GRAY + "Downloads a file from a given URL."; - } - - @Override - public String getSyntax() { - return "/customdisc download "; - } - - @Override - public void perform(Player player, String[] args) { - // /cd download url filename - // [0] [1] [2] - - if (!player.hasPermission("customdiscs.download")) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString()); - player.sendMessage(textComponent); - return; - } - - if (args.length!=3) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_ARGUMENTS.toString().replace("%command_syntax%", getSyntax())); - player.sendMessage(textComponent); - return; - } - - Bukkit.getScheduler().runTaskAsynchronously(customDiscs, () -> { - try { - URL fileURL = new URL(args[1]); - String filename = args[2]; - if (filename.contains("../")) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FILENAME.toString()); - player.sendMessage(textComponent); - return; - } - - System.out.println(filename); - - if (!getFileExtension(filename).equals("wav") && !getFileExtension(filename).equals("mp3") && !getFileExtension(filename).equals("flac")) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FORMAT.toString()); - player.sendMessage(textComponent); - return; - } - - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.DOWNLOADING_FILE.toString()); - player.sendMessage(textComponent); - Path downloadPath = Path.of(customDiscs.getDataFolder().getPath(), "musicdata", filename); - File downloadFile = new File(downloadPath.toUri()); - - URLConnection connection = fileURL.openConnection(); - - if (connection != null) { - long size = connection.getContentLengthLong() / 1048576; - if (size > customDiscs.getConfig().getInt("max-download-size", 50)) { - Component textComponent2 = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.FILE_TOO_LARGE.toString().replace("%max_download_size%", String.valueOf(customDiscs.getConfig().getInt("max-download-size", 50)))); - player.sendMessage(textComponent2); - return; - } - } - - FileUtils.copyURLToFile(fileURL, downloadFile); - - Component fileDownloaded = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.SUCCESSFUL_DOWNLOAD.toString().replace("%file_path%", "plugins/CustomDiscs/musicdata/" + filename)); - Component createDisc = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_DISC.toString().replace("%filename%", filename)); - - player.sendMessage(fileDownloaded); - player.sendMessage(createDisc); - } catch (IOException e) { - Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.DOWNLOAD_ERROR.toString()); - player.sendMessage(textComponent); - e.printStackTrace(); - } - }); - } - - private String getFileExtension(String s) { - int index = s.lastIndexOf("."); - if (index > 0) { - return s.substring(index + 1); - } else { - return ""; - } - } - -} diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java new file mode 100644 index 0000000..21744a1 --- /dev/null +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java @@ -0,0 +1,101 @@ +package me.Navoei.customdiscsplugin.command.SubCommands; + +import dev.jorel.commandapi.CommandAPICommand; +import dev.jorel.commandapi.arguments.StringArgument; +import dev.jorel.commandapi.arguments.TextArgument; +import dev.jorel.commandapi.executors.CommandArguments; +import me.Navoei.customdiscsplugin.CustomDiscs; +import me.Navoei.customdiscsplugin.language.Lang; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Path; +import java.util.Objects; + +public class DownloadSubCommand extends CommandAPICommand { + private final CustomDiscs plugin; + + public DownloadSubCommand(CustomDiscs plugin) { + super("download"); + this.plugin = plugin; + + this.withFullDescription(ChatColor.GRAY + "Downloads a file from a given URL."); + this.withUsage("/customdisc download "); + + this.withArguments(new TextArgument("url")); + this.withArguments(new StringArgument("filename")); + + this.executesPlayer(this::onCommandPlayer); + this.executesConsole(this::onCommandConsole); + } + + private int onCommandPlayer(Player player, CommandArguments arguments) { + if (!player.hasPermission("customdiscs.download")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString())); + return 1; + } + + Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { + try { + URL fileURL = new URL(Objects.requireNonNull(arguments.getByClass("url", String.class))); + String filename = Objects.requireNonNull(arguments.getByClass("filename", String.class)); + if (filename.contains("../")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FILENAME.toString())); + return; + } + + System.out.println(filename); + + if (!getFileExtension(filename).equals("wav") && !getFileExtension(filename).equals("mp3") && !getFileExtension(filename).equals("flac")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FORMAT.toString())); + return; + } + + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.DOWNLOADING_FILE.toString())); + + URLConnection connection = fileURL.openConnection(); + if (connection != null) { + long size = connection.getContentLengthLong() / 1048576; + if (size > this.plugin.getConfig().getInt("max-download-size", 50)) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.FILE_TOO_LARGE.toString().replace("%max_download_size%", String.valueOf(this.plugin.getConfig().getInt("max-download-size", 50))))); + return; + } + } + + Path downloadPath = Path.of(this.plugin.getDataFolder().getPath(), "musicdata", filename); + File downloadFile = new File(downloadPath.toUri()); + FileUtils.copyURLToFile(fileURL, downloadFile); + + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.SUCCESSFUL_DOWNLOAD.toString().replace("%file_path%", "plugins/CustomDiscs/musicdata/" + filename))); + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_DISC.toString().replace("%filename%", filename))); + } catch (IOException e) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.DOWNLOAD_ERROR.toString())); + e.printStackTrace(); + } + }); + + return 1; + } + + private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { + executor.sendMessage(ChatColor.RED + "Only players can use this command!"); + return 1; + } + + private String getFileExtension(String s) { + int index = s.lastIndexOf("."); + if (index > 0) { + return s.substring(index + 1); + } else { + return ""; + } + } +} diff --git a/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java b/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java index 1b4ce4c..f4e161d 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java +++ b/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java @@ -7,7 +7,6 @@ public enum Lang { PREFIX("prefix", "&8[&6CustomDiscs&8]&r"), NO_PERMISSION("no-permission", "&rYou do not have permission to execute this command."), INVALID_FILENAME("invalid-filename", "&rThis is an invalid filename!"), - NO_DISC_NAME_PROVIDED("no-disc-name-provided", "&rYou must provide a name for your disc."), INVALID_FORMAT("invalid-format", "&rFile must be in wav, flac, or mp3 format!"), FILE_NOT_FOUND("file-not-found", "&rFile not found!"), INVALID_ARGUMENTS("invalid-arguments", "&rInsufficient arguments. &7(&a%command_syntax%&7)"),