diff --git a/build.gradle b/build.gradle index a7c7330..f8a25ac 100644 --- a/build.gradle +++ b/build.gradle @@ -41,7 +41,6 @@ dependencies { shadow "dev.jorel:commandapi-bukkit-shade:${command_api_version}" compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "5.1.0"; - } repositories { @@ -57,6 +56,7 @@ repositories { } maven { url "https://repo.dmulloy2.net/repository/public/" } maven { url = "https://repo.codemc.org/repository/maven-public/" } + mavenLocal() } diff --git a/gradle.properties b/gradle.properties index e880e35..4b66b98 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,13 +5,13 @@ java_version=21 mp3spi_version=1.9.5.4 bukkit_api_version=1.20 -bukkit_version=1.21-R0.1-SNAPSHOT +bukkit_version=1.21.1-R0.1-SNAPSHOT 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.3 -plugin_version=3.1 +plugin_version=3.2a maven_group=me.Navoei.customdiscsplugin archives_base_name=custom-discs \ No newline at end of file diff --git a/readme.md b/readme.md index 1551c43..53aee0e 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# Custom Discs v3.1 for Paper 1.21 +# Custom Discs v3.2a for Paper 1.21.1 ("a" for Athar's fork release from the original plugin here : https://github.com/Navoei/CustomDiscs ) A Paper fork of henkelmax's Audio Player. - Play custom music discs using the Simple Voice Chat API. (The voice chat mod is required on the client and server.) @@ -15,10 +15,15 @@ Set the range of a disc: - To set the active range of a playable disc, just use the command ```/cd range ``` where is between 1 and the max value set in the config file (default : 256) - Example: ```/cd range 100``` +Set the cooldown for a modified goat horn: +- To set a different cooldown timer than the one set by the config, just use the command ```/cd goatcooldown ``` where is between 0 and the max value set in the config file (default : 6000) +- Example: ```/cd goatcooldown 7``` + Permission Nodes (Required to run the commands. Playing discs does not require a permission.): - ```customdiscs.create``` to create a disc - ```customdiscs.download``` to download a file - ```customdiscs.range``` to set the range of the disc +- ```customdiscs.horncooldown``` to set the cooldown for your modified goat horn Dependencies: - This plugin depends on the latest version of ProtocolLib for 1.21 and SimpleVoiceChatBukkit version 2.5.16. @@ -39,9 +44,15 @@ music-disc-max-distance: 256 # The master volume of music discs from 0-1. (You can set values like 0.5 for 50% volume). music-disc-volume: 1 -#The maximum download size in megabytes. +# The maximum download size in megabytes. max-download-size: 50 +# The default cooldown time for horns in seconds from 1 to the max value of horn-max-cooldown. +horn-cooldown: 7 + +# The default max cooldown time for horns in seconds (5 minutes by default). +horn-max-cooldown: 15 + #Custom Discs Help Page help: - "&8-[&6CustomDiscs Help Page&8]-" @@ -71,6 +82,10 @@ now-playing: "&6Now playing: %song_name%" disc-converted: "&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &7JukeboxPlayableComponent&f." invalid-range: "&cYou need to chose a range between 1 and %range_value%" create-custom-range: "&7Your range is set to: &a\"%custom_range%\"." +not-holding-goathorn: "&rYou must hold a goat horn in your main hand." +not-holding-modified-goathorn: "&rYou must hold a modified goat horn in your main hand." +invalid-cooldown: "&rYou need to chose a cooldown between 0 and %cooldown_value%" +create-custom-goat-cooldown: "&7Your goat horn cooldown is set to: &a\"%custom_goat_cooldown%\"." ``` diff --git a/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java b/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java index 78a7623..596d6a3 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java +++ b/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java @@ -12,6 +12,7 @@ import dev.jorel.commandapi.CommandAPI; import dev.jorel.commandapi.CommandAPIBukkitConfig; import me.Navoei.customdiscsplugin.command.CustomDiscCommand; import me.Navoei.customdiscsplugin.event.JukeBox; +import me.Navoei.customdiscsplugin.event.HornPlay; import me.Navoei.customdiscsplugin.language.Lang; import org.bukkit.NamespacedKey; import org.bukkit.block.Jukebox; @@ -37,6 +38,9 @@ public final class CustomDiscs extends JavaPlugin { public float musicDiscDistance; public float musicDiscMaxDistance; public float musicDiscVolume; + public float hornCooldown; + public int hornMaxCooldown; + public int hornMaxCooldownTicks; @Override public void onLoad() { @@ -70,11 +74,15 @@ public final class CustomDiscs extends JavaPlugin { } getServer().getPluginManager().registerEvents(new JukeBox(), this); + getServer().getPluginManager().registerEvents(new HornPlay(), this); getServer().getPluginManager().registerEvents(new HopperManager(), this); - musicDiscDistance = getConfig().getInt("music-disc-distance"); - musicDiscMaxDistance = getConfig().getInt("music-disc-max-distance"); + musicDiscDistance = Objects.requireNonNull(getConfig().getInt("music-disc-distance")); + musicDiscMaxDistance = Objects.requireNonNull(getConfig().getInt("music-disc-max-distance")); musicDiscVolume = Float.parseFloat(Objects.requireNonNull(getConfig().getString("music-disc-volume"))); + hornCooldown = Float.parseFloat(Objects.requireNonNull(getConfig().getString("horn-cooldown"))); + hornMaxCooldown = Objects.requireNonNull(getConfig().getInt("horn-max-cooldown")); + hornMaxCooldownTicks = (Objects.requireNonNull(getConfig().getInt("horn-max-cooldown")) * 20); ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); @@ -88,7 +96,7 @@ public final class CustomDiscs extends JavaPlugin { if (!jukebox.getRecord().hasItemMeta()) return; - if (jukebox.getRecord().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(CustomDiscs.getInstance(), "customdisc"), PersistentDataType.STRING)) { + if (jukebox.getRecord().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(this.plugin, "customdisc"), PersistentDataType.STRING)) { jukebox.stopPlaying(); event.setCancelled(true); } @@ -117,6 +125,10 @@ public final class CustomDiscs extends JavaPlugin { public static boolean isMusicDisc(Player p) { return p.getInventory().getItemInMainHand().getType().toString().contains("MUSIC_DISC"); } + + public static boolean isGoatHorn(Player p) { + return p.getInventory().getItemInMainHand().getType().toString().contains("GOAT_HORN"); + } /** * Load the lang.yml file. diff --git a/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java b/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java index 4a0b04f..af11c58 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java +++ b/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java @@ -100,6 +100,61 @@ public class PlayerManager { } }); } + + public void playLocationalAudioHorn(VoicechatServerApi api, Path soundFilePath, Player block, Component actionbarComponent, float range) { + UUID id = UUID.nameUUIDFromBytes(block.getLocation().toString().getBytes()); + + LocationalAudioChannel audioChannel = api.createLocationalAudioChannel(id, api.fromServerLevel(block.getWorld()), api.createPosition(block.getLocation().getX() + 0.5d, block.getLocation().getY() + 0.5d, block.getLocation().getZ() + 0.5d)); + + if (audioChannel == null) return; + + audioChannel.setCategory(VoicePlugin.GOAT_HORN_CATEGORY); + audioChannel.setDistance(range); + + AtomicBoolean stopped = new AtomicBoolean(); + AtomicReference player = new AtomicReference<>(); + + playerMap.put(id, () -> { + synchronized (stopped) { + stopped.set(true); + de.maxhenkel.voicechat.api.audiochannel.AudioPlayer audioPlayer = player.get(); + if (audioPlayer != null) { + audioPlayer.stopPlaying(); + } + } + }); + + executorService.execute(() -> { + Collection playersInRange = api.getPlayersInRange(api.fromServerLevel(block.getWorld()), api.createPosition(block.getLocation().getX() + 0.5d, block.getLocation().getY() + 0.5d, block.getLocation().getZ() + 0.5d), range); + + de.maxhenkel.voicechat.api.audiochannel.AudioPlayer audioPlayer = playChannelHorn(api, audioChannel, block, soundFilePath, playersInRange); + + for (ServerPlayer serverPlayer : playersInRange) { + Player bukkitPlayer = (Player) serverPlayer.getPlayer(); + bukkitPlayer.sendActionBar(actionbarComponent); + } + + if (audioPlayer == null) { + playerMap.remove(id); + return; + } + + audioPlayer.setOnStopped(() -> { + + //Bukkit.getScheduler().runTask(CustomDiscs.getInstance(), () -> HopperManager.instance().discToHopper(block)); + + playerMap.remove(id); + }); + + synchronized (stopped) { + if (!stopped.get()) { + player.set(audioPlayer); + } else { + audioPlayer.stopPlaying(); + } + } + }); + } @Nullable private de.maxhenkel.voicechat.api.audiochannel.AudioPlayer playChannel(VoicechatServerApi api, AudioChannel audioChannel, Block block, Path soundFilePath, Collection playersInRange) { @@ -118,6 +173,24 @@ public class PlayerManager { return null; } } + + @Nullable + private de.maxhenkel.voicechat.api.audiochannel.AudioPlayer playChannelHorn(VoicechatServerApi api, AudioChannel audioChannel, Player block, Path soundFilePath, Collection playersInRange) { + try { + short[] audio = readSoundFile(soundFilePath); + AudioPlayer audioPlayer = api.createAudioPlayer(audioChannel, api.createEncoder(), audio); + audioPlayer.startPlaying(); + return audioPlayer; + } catch (Exception e) { + e.printStackTrace(); + Bukkit.getLogger().info("Error Occurred At: " + block.getLocation()); + for (ServerPlayer serverPlayer : playersInRange) { + Player bukkitPlayer = (Player) serverPlayer.getPlayer(); + bukkitPlayer.sendMessage(NamedTextColor.RED + "An error has occurred while trying to play this horn."); + } + return null; + } + } private static short[] readSoundFile(Path file) throws UnsupportedAudioFileException, IOException, LineUnavailableException { return VoicePlugin.voicechatApi.getAudioConverter().bytesToShorts(convertFormat(file, FORMAT)); diff --git a/src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java b/src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java index 2b41b27..008de83 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java +++ b/src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java @@ -16,12 +16,20 @@ import java.util.Enumeration; public class VoicePlugin implements VoicechatPlugin { public static String MUSIC_DISC_CATEGORY = "music_discs"; + + public static String GOAT_HORN_CATEGORY = "goat_horns"; + + public static String PLAYER_HEAD_CATEGORY = "player_heads"; public static VoicechatApi voicechatApi; @Nullable public static VoicechatServerApi voicechatServerApi; @Nullable public static VolumeCategory musicDiscs; + @Nullable + public static VolumeCategory goatHorns; + @Nullable + public static VolumeCategory playerHeads; /** * @return the unique ID for this voice chat plugin @@ -61,6 +69,22 @@ public class VoicePlugin implements VoicechatPlugin { .setIcon(getMusicDiscIcon()) .build(); voicechatServerApi.registerVolumeCategory(musicDiscs); + + goatHorns = voicechatServerApi.volumeCategoryBuilder() + .setId(GOAT_HORN_CATEGORY) + .setName("Goat Horns") + .setDescription("The volume of goat horns") + .setIcon(getGoatHornsIcon()) + .build(); + voicechatServerApi.registerVolumeCategory(goatHorns); + + playerHeads = voicechatServerApi.volumeCategoryBuilder() + .setId(PLAYER_HEAD_CATEGORY) + .setName("Player Heads") + .setDescription("The volume of player heads (not enabled)") + .setIcon(getPlayerHeadsIcon()) + .build(); + voicechatServerApi.registerVolumeCategory(playerHeads); } @@ -90,5 +114,59 @@ public class VoicePlugin implements VoicechatPlugin { } return null; } + + private int[][] getGoatHornsIcon() { + try { + Enumeration resources = CustomDiscs.getInstance().getClass().getClassLoader().getResources("goat_horn_category.png"); -} + while (resources.hasMoreElements()) { + BufferedImage bufferedImage = ImageIO.read(resources.nextElement().openStream()); + if (bufferedImage.getWidth() != 16) { + continue; + } + if (bufferedImage.getHeight() != 16) { + continue; + } + int[][] image = new int[16][16]; + for (int x = 0; x < bufferedImage.getWidth(); x++) { + for (int y = 0; y < bufferedImage.getHeight(); y++) { + image[x][y] = bufferedImage.getRGB(x, y); + } + } + return image; + } + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private int[][] getPlayerHeadsIcon() { + try { + Enumeration resources = CustomDiscs.getInstance().getClass().getClassLoader().getResources("player_head_category.png"); + + while (resources.hasMoreElements()) { + BufferedImage bufferedImage = ImageIO.read(resources.nextElement().openStream()); + if (bufferedImage.getWidth() != 16) { + continue; + } + if (bufferedImage.getHeight() != 16) { + continue; + } + int[][] image = new int[16][16]; + for (int x = 0; x < bufferedImage.getWidth(); x++) { + for (int y = 0; y < bufferedImage.getHeight(); y++) { + image[x][y] = bufferedImage.getRGB(x, y); + } + } + return image; + } + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} \ No newline at end of file diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java index 5d9f1b0..4005d47 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java +++ b/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java @@ -6,6 +6,7 @@ import me.Navoei.customdiscsplugin.CustomDiscs; import me.Navoei.customdiscsplugin.command.SubCommands.CreateSubCommand; import me.Navoei.customdiscsplugin.command.SubCommands.DownloadSubCommand; import me.Navoei.customdiscsplugin.command.SubCommands.SetRangeSubCommand; +import me.Navoei.customdiscsplugin.command.SubCommands.SetHornCooldownSubCommand; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.ConsoleCommandSender; @@ -25,6 +26,7 @@ public class CustomDiscCommand extends CommandAPICommand { this.withSubcommand(new CreateSubCommand(plugin)); this.withSubcommand(new DownloadSubCommand(plugin)); this.withSubcommand(new SetRangeSubCommand(plugin)); + this.withSubcommand(new SetHornCooldownSubCommand(plugin)); this.executesPlayer(this::onCommandPlayer); this.executesConsole(this::onCommandConsole); @@ -40,7 +42,7 @@ public class CustomDiscCommand extends CommandAPICommand { } private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { - executor.sendMessage(NamedTextColor.RED + "Only players can use this command!"); + executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!"); return 1; } } diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java index 8501bd4..07f3600 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java @@ -27,6 +27,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; +import org.bukkit.Bukkit; +import org.bukkit.Material; public class CreateSubCommand extends CommandAPICommand { private final CustomDiscs plugin; @@ -59,7 +61,7 @@ public class CreateSubCommand extends CommandAPICommand { } private int onCommandPlayer(Player player, CommandArguments arguments) { - if (!CustomDiscs.isMusicDisc(player)) { + if (!CustomDiscs.isMusicDisc(player) && !CustomDiscs.isGoatHorn(player)) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_DISC.toString())); return 1; } @@ -89,22 +91,80 @@ public class CreateSubCommand extends CommandAPICommand { } 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); + + if (CustomDiscs.isMusicDisc(player)) { + // IF CD + // 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); + } else if (CustomDiscs.isGoatHorn(player)) { + // IF HORN + int removedHornState = 0; + + ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand()); + ItemMeta theItemMeta = disc.getItemMeta(); + PersistentDataContainer data = theItemMeta.getPersistentDataContainer(); + Float retrieveCustomRangeIfSet = data.get(new NamespacedKey(this.plugin, "customsoundrange"), PersistentDataType.FLOAT); + if (retrieveCustomRangeIfSet == null) { + retrieveCustomRangeIfSet = this.plugin.musicDiscDistance; + } + + if (player.getInventory().getItemInMainHand().getAmount() == 1) { + player.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); + removedHornState = 1; + } else { + player.getInventory().getItemInMainHand().setAmount(player.getInventory().getItemInMainHand().getAmount()-1); + removedHornState = 1; + } + if (removedHornState == 1) { + var namespaceHorn = new NamespacedKey(this.plugin, "customhorn"); + var namespaceCustomsoundrange = new NamespacedKey(this.plugin, "customsoundrange"); + var namespaceCustomhorncooldown = new NamespacedKey(this.plugin, "customhorncoolodwn"); + + int setHornCooldown; + if(data.has(namespaceCustomhorncooldown, PersistentDataType.INTEGER)) { + setHornCooldown = Math.min(data.get(namespaceCustomhorncooldown, PersistentDataType.INTEGER), CustomDiscs.getInstance().hornMaxCooldownTicks); + } else { + setHornCooldown = Math.min(Math.round(CustomDiscs.getInstance().hornCooldown * 20), CustomDiscs.getInstance().hornMaxCooldownTicks); + } + + //TEST COMMAND LOCAL : /give PLAYER minecraft:goat_horn{HideFlags:255,instrument:"",display:{Lore:['{"italic":false,"color":"gray","text":"customName(readQuotes(args))"}']},PublicBukkitValues:{"namespaceHorn":"filename"}} + //String command = "minecraft:give "+player.getName()+" minecraft:goat_horn[minecraft:instrument={sound_event:{sound_id:\"intentionally_empty\"},use_duration: 140,range:256F},minecraft:custom_data={PublicBukkitValues:{\""+namespaceHorn+"\":\""+filename+"\"}},minecraft:lore=['{\"bold\":false,\"color\":\"gray\",\"italic\":false,\"text\":\""+song_name+"\",\"underlined\":false}']]"; + /*String command = "minecraft:give " + player.getName() + " minecraft:goat_horn{" + + "minecraft:instrument:{sound_event:{sound_id:\"intentionally_empty\"},use_duration:140,range:256F}," + + "minecraft:custom_data:{PublicBukkitValues:{\"" + namespaceHorn + "\":\"" + filename + "\"}}," + + "minecraft:lore:[{\"bold\":false,\"color\":\"gray\",\"italic\":false,\"text\":\"" + song_name + "\",\"underlined\":false}]" + + "}";*/ + //Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + + String itemCommand = "minecraft:give " + player.getName() + " minecraft:goat_horn[" + + "minecraft:instrument={sound_event:{sound_id:\"intentionally_empty\"},use_duration:140,range:256F}," + + "minecraft:custom_data={PublicBukkitValues:{\"" + namespaceHorn + "\":\"" + filename + "\",\""+namespaceCustomsoundrange+"\":"+retrieveCustomRangeIfSet+"f,\"" + namespaceCustomhorncooldown + "\":" + setHornCooldown + "}}," + + "minecraft:lore=['{\"bold\":false,\"color\":\"gray\",\"italic\":false,\"text\":\"" + song_name + "\",\"underlined\":false}']" + + "]"; + + // Dispatch the command to give the item + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), itemCommand); + } else { + player.sendMessage("Horn deletion error"); + } + //player.getInventory().getItemInMainHand().subtract(); + } else { + // IF ELSE + return 1; + } 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))); @@ -112,7 +172,7 @@ public class CreateSubCommand extends CommandAPICommand { } private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { - executor.sendMessage(NamedTextColor.RED + "Only players can use this command!"); + executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!"); return 1; } diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java index e80c9d5..6acf8c4 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java @@ -86,7 +86,7 @@ public class DownloadSubCommand extends CommandAPICommand { } private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { - executor.sendMessage(NamedTextColor.RED + "Only players can use this command!"); + executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!"); return 1; } diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/SetHornCooldownSubCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/SetHornCooldownSubCommand.java new file mode 100644 index 0000000..1bc8008 --- /dev/null +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/SetHornCooldownSubCommand.java @@ -0,0 +1,93 @@ +package me.Navoei.customdiscsplugin.command.SubCommands; + +import dev.jorel.commandapi.CommandAPICommand; +import dev.jorel.commandapi.arguments.FloatArgument; +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 net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import java.util.Objects; +import org.bukkit.Bukkit; + +public class SetHornCooldownSubCommand extends CommandAPICommand { + private final CustomDiscs plugin; + + public SetHornCooldownSubCommand(CustomDiscs plugin) { + super("goatcooldown"); + this.plugin = plugin; + + this.withFullDescription(NamedTextColor.GRAY + "Set the cooldown for a modified goat horn (range from 0 to "+ this.plugin.hornMaxCooldown +" in seconds)."); + this.withUsage("/cd goatcooldown "); + + this.withArguments(new FloatArgument("goatcooldown")); + + this.executesPlayer(this::onCommandPlayer); + this.executesConsole(this::onCommandConsole); + } + + private int onCommandPlayer(Player player, CommandArguments arguments) { + if (!CustomDiscs.isGoatHorn(player)) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_GOATHORN.toString())); + return 1; + } + + if (!player.hasPermission("customdiscs.horncooldown")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString())); + return 1; + } + + Float goatcooldown = Objects.requireNonNull(arguments.getByClass("goatcooldown", Float.class)); + + if ( goatcooldown < 0 || goatcooldown > this.plugin.hornMaxCooldown) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_COOLDOWN.toString().replace("%cooldown_value%", Float.toString(this.plugin.hornMaxCooldown)))); + return 1; + } + + //Sets the lore of the item to the quotes from the command. + ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand()); + ItemMeta theItemMeta = disc.getItemMeta(); + + PersistentDataContainer data = theItemMeta.getPersistentDataContainer(); + + var namespaceHorn = new NamespacedKey(this.plugin, "customhorn"); + String retrieveCustomHornFile = data.get(namespaceHorn, PersistentDataType.STRING); + if (retrieveCustomHornFile == null || retrieveCustomHornFile.compareTo("null") == 0) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_MODIFIED_GOATHORN.toString())); + return 1; + } + + var namespaceCustomsoundrange = new NamespacedKey(this.plugin, "customsoundrange"); + Float retrieveCustomsoundrange = data.get(namespaceCustomsoundrange, PersistentDataType.FLOAT); + + var namespaceCustomhorncooldown = new NamespacedKey(this.plugin, "customhorncoolodwn"); + int setCustomGoatcooldown; + if (goatcooldown == 0) { + setCustomGoatcooldown = 1; + } else { + setCustomGoatcooldown = Math.min(Math.round(goatcooldown * 20), CustomDiscs.getInstance().hornMaxCooldownTicks); + } + + String command = "minecraft:item modify entity "+player.getName()+" weapon.mainhand {\"function\":\"minecraft:set_components\",\"components\":{\"minecraft:custom_data\":\"{PublicBukkitValues:{\\\""+namespaceHorn+"\\\":\\\""+retrieveCustomHornFile+"\\\",\\\""+namespaceCustomsoundrange+"\\\":"+retrieveCustomsoundrange+"f,\\\""+namespaceCustomhorncooldown+"\\\":"+setCustomGoatcooldown+"}}\"}}"; + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + + + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_GOAT_COOLDOWN.toString().replace("%custom_goat_cooldown%", Float.toString(goatcooldown)))); + + return 1; + } + + private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { + executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!"); + return 1; + } + +} diff --git a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/SetRangeSubCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/SetRangeSubCommand.java index 8bec24f..b5fbc1d 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/SetRangeSubCommand.java +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/SetRangeSubCommand.java @@ -19,6 +19,7 @@ import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import java.util.Objects; +import org.bukkit.Bukkit; public class SetRangeSubCommand extends CommandAPICommand { private final CustomDiscs plugin; @@ -37,7 +38,7 @@ public class SetRangeSubCommand extends CommandAPICommand { } private int onCommandPlayer(Player player, CommandArguments arguments) { - if (!CustomDiscs.isMusicDisc(player)) { + if (!CustomDiscs.isMusicDisc(player) && !CustomDiscs.isGoatHorn(player)) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_DISC.toString())); return 1; } @@ -59,9 +60,28 @@ public class SetRangeSubCommand extends CommandAPICommand { ItemMeta theItemMeta = disc.getItemMeta(); PersistentDataContainer data = theItemMeta.getPersistentDataContainer(); - data.set(new NamespacedKey(this.plugin, "customsoundrange"), PersistentDataType.FLOAT, range); - player.getInventory().getItemInMainHand().setItemMeta(theItemMeta); + if (CustomDiscs.isMusicDisc(player)) { + data.set(new NamespacedKey(this.plugin, "customsoundrange"), PersistentDataType.FLOAT, range); + player.getInventory().getItemInMainHand().setItemMeta(theItemMeta); + } else if (CustomDiscs.isGoatHorn(player)) { + var namespaceHorn = new NamespacedKey(this.plugin, "customhorn"); + String retrieveCustomHornFile = data.get(namespaceHorn, PersistentDataType.STRING); + if (retrieveCustomHornFile == null || retrieveCustomHornFile.compareTo("null") == 0) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_MODIFIED_GOATHORN.toString())); + return 1; + } + + Float setCustomHornRange = range; + + var namespaceCustomsoundrange = new NamespacedKey(this.plugin, "customsoundrange"); + var namespaceCustomhorncooldown = new NamespacedKey(this.plugin, "customhorncoolodwn"); + int retrieveCustomhorncooldown = data.get(namespaceCustomhorncooldown, PersistentDataType.INTEGER); + + String command = "minecraft:item modify entity "+player.getName()+" weapon.mainhand {\"function\":\"minecraft:set_components\",\"components\":{\"minecraft:custom_data\":\"{PublicBukkitValues:{\\\""+namespaceHorn+"\\\":\\\""+retrieveCustomHornFile+"\\\",\\\""+namespaceCustomsoundrange+"\\\":"+setCustomHornRange+"f,\\\""+namespaceCustomhorncooldown+"\\\":"+retrieveCustomhorncooldown+"}}\"}}"; + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + + } player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_RANGE.toString().replace("%custom_range%", Float.toString(range)))); @@ -69,7 +89,7 @@ public class SetRangeSubCommand extends CommandAPICommand { } private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { - executor.sendMessage(NamedTextColor.RED + "Only players can use this command!"); + executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!"); return 1; } diff --git a/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java b/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java index 5c8e967..0d8db19 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java +++ b/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java @@ -20,7 +20,11 @@ public enum Lang { NOW_PLAYING("now-playing","&6Now playing: %song_name%"), DISC_CONVERTED("disc-converted", "&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &7JukeboxPlayableComponent&f."), INVALID_RANGE("invalid-range","&rYou need to chose a range between 1 and %range_value%"), - CREATE_CUSTOM_RANGE("create-custom-range", "&7Your range is set to: &a\"%custom_range%\"."); + CREATE_CUSTOM_RANGE("create-custom-range", "&7Your range is set to: &a\"%custom_range%\"."), + NOT_HOLDING_GOATHORN("not-holding-goathorn", "&cYou must hold a goat horn in your main hand."), + NOT_HOLDING_MODIFIED_GOATHORN("not-holding-modified-goathorn", "&cYou must hold a modified goat horn in your main hand."), + INVALID_COOLDOWN("invalid-cooldown","&cYou need to chose a cooldown between 0 and %cooldown_value%"), + CREATE_CUSTOM_GOAT_COOLDOWN("create-custom-goat-cooldown", "&7Your goat horn cooldown is set to: &a\"%custom_goat_cooldown%\"."); private final String path; private final String def; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 7ebbf26..6823c95 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -9,9 +9,15 @@ music-disc-max-distance: 256 # The master volume of music discs from 0-1. (You can set values like 0.5 for 50% volume). music-disc-volume: 1 -#The maximum download size in megabytes. +# The maximum download size in megabytes. max-download-size: 50 +# The default cooldown time for horns in seconds from 1 to the max value of horn-max-cooldown. +horn-cooldown: 7 + +# The default max cooldown time for horns in seconds (5 minutes by default). +horn-max-cooldown: 300 + #Custom Discs Help Page help: - "&8-[&6CustomDiscs Help Page&8]-" diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index 05c22da..0059485 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -17,3 +17,7 @@ now-playing: "&6Now playing: %song_name%" disc-converted: "&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &7JukeboxPlayableComponent&f." invalid-range: "&cYou need to chose a range between 1 and %range_value%" create-custom-range: "&7Your range is set to: &a\"%custom_range%\"." +not-holding-goathorn: "&cYou must hold a goat horn in your main hand." +not-holding-modified-goathorn: "&cYou must hold a modified goat horn in your main hand." +invalid-cooldown: "&cYou need to chose a cooldown between 0 and %cooldown_value%" +create-custom-goat-cooldown: "&7Your goat horn cooldown is set to: &a\"%custom_goat_cooldown%\"." \ No newline at end of file