diff --git a/build.gradle b/build.gradle index bebcde2..341054b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'io.github.goooler.shadow' version '8.1.7' + id "com.gradleup.shadow" version "8.3.4" } sourceCompatibility = JavaLanguageVersion.of(java_version as int) @@ -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,12 +56,13 @@ repositories { } maven { url "https://repo.dmulloy2.net/repository/public/" } maven { url = "https://repo.codemc.org/repository/maven-public/" } + mavenLocal() } shadowJar { configurations = [project.configurations.shadow] - archiveClassifier.set("shadow-dev") + archiveClassifier.set("dev") //relocate 'javazoom', "me.navoei.${mod_id}.javazoom" //relocate 'org.tritonus', "me.navoei.${mod_id}.tritonus" diff --git a/gradle.properties b/gradle.properties index a2668ef..95db702 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,14 +4,14 @@ java_version=21 mp3spi_version=1.9.5.4 -bukkit_api_version=1.20 -bukkit_version=1.21-R0.1-SNAPSHOT +bukkit_api_version=1.21 +bukkit_version=1.21.3-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.2 +command_api_version=9.6.0 -plugin_version=3.0 +plugin_version=3.3.0a maven_group=me.Navoei.customdiscsplugin archives_base_name=custom-discs \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aeef431..2598c65 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sun Aug 11 17:52:06 EDT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/readme.md b/readme.md index 7419ef7..6d07b87 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# Custom Discs v3.0 for Paper 1.21 +# Custom Discs v3.3.0a for Paper 1.21.3 ("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.) @@ -11,9 +11,19 @@ Downloading Files: - Example: ```/cd download https://example.com/mysong mysong.mp3``` - Direct Google Drive links: https://lonedev6.github.io/gddl/ +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. @@ -28,16 +38,26 @@ Default Config.yml: # The distance from which music discs can be heard in blocks. music-disc-distance: 16 +# The max distance from which music discs can be heard in blocks. +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]-" - "&aAuthor&7: &6Navoei" + - "&aContributors&7: &6alfw / &6Athar42" - "&fGit&0Hub&7: &9&ohttps://github.com/Navoei/CustomDiscs" ``` @@ -60,6 +80,12 @@ create-disc: "&aCreate a disc by doing &7/cd create %filename% \"Custom Lore\"&a download-error: "&cAn error has occurred while downloading." 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 6fca3fe..09b1aa3 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java +++ b/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java @@ -12,9 +12,11 @@ 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; +import org.bukkit.entity.Player; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.persistence.PersistentDataType; import org.bukkit.plugin.java.JavaPlugin; @@ -34,7 +36,11 @@ public final class CustomDiscs extends JavaPlugin { public static YamlConfiguration LANG; public static File LANG_FILE; public float musicDiscDistance; + public float musicDiscMaxDistance; public float musicDiscVolume; + public float hornCooldown; + public int hornMaxCooldown; + public int hornMaxCooldownTicks; @Override public void onLoad() { @@ -68,10 +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"); + 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(); @@ -85,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); } @@ -110,7 +121,15 @@ public final class CustomDiscs extends JavaPlugin { public static CustomDiscs getInstance() { return instance; } - + + 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. * @@ -131,7 +150,7 @@ public final class CustomDiscs extends JavaPlugin { } } catch (IOException e) { e.printStackTrace(); // So they notice - log.severe("Failed to create lang.yml for MyHomes."); + log.severe("Failed to create lang.yml for CustomDiscs."); log.severe("Now disabling..."); this.setEnabled(false); // Without it loaded, we can't send them messages } @@ -148,7 +167,7 @@ public final class CustomDiscs extends JavaPlugin { try { conf.save(getLangFile()); } catch (IOException e) { - log.log(Level.WARNING, "Failed to save lang.yml for MyHomes"); + log.log(Level.WARNING, "Failed to save lang.yml for CustomDiscs"); log.log(Level.WARNING, "Now disabling..."); e.printStackTrace(); } diff --git a/src/main/java/me/Navoei/customdiscsplugin/HopperManager.java b/src/main/java/me/Navoei/customdiscsplugin/HopperManager.java index 94ca933..3265dcd 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/HopperManager.java +++ b/src/main/java/me/Navoei/customdiscsplugin/HopperManager.java @@ -8,7 +8,7 @@ import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.block.Block; import org.bukkit.block.BlockState; -import org.bukkit.block.Container; +//import org.bukkit.block.Container; import org.bukkit.block.Jukebox; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -17,22 +17,31 @@ import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.components.JukeboxPlayableComponent; import org.bukkit.persistence.PersistentDataType; import java.nio.file.Path; import java.util.Objects; +import org.bukkit.entity.minecart.HopperMinecart; +import org.bukkit.inventory.InventoryHolder; + +// Used only if logger is needed +//import java.util.logging.Logger; +//import org.bukkit.Bukkit; public class HopperManager implements Listener { CustomDiscs customDiscs = CustomDiscs.getInstance(); PlayerManager playerManager = PlayerManager.instance(); + + //private static final Logger logger = Bukkit.getLogger(); // or Logger.getLogger("Minecraft"); @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onJukeboxInsertFromHopper(InventoryMoveItemEvent event) { - + //logger.warning("Enter : onJukeboxInsertFromHopper"); if (event.getDestination().getLocation() == null) return; if (!event.getDestination().getType().equals(InventoryType.JUKEBOX)) return; if (!isCustomMusicDisc(event.getItem())) return; @@ -43,6 +52,15 @@ public class HopperManager implements Listener { ItemMeta discMeta = event.getItem().getItemMeta(); String soundFileName = discMeta.getPersistentDataContainer().get(new NamespacedKey(customDiscs, "customdisc"), PersistentDataType.STRING); + + PersistentDataContainer persistentDataContainer = event.getItem().getItemMeta().getPersistentDataContainer(); + float range = CustomDiscs.getInstance().musicDiscDistance; + NamespacedKey customSoundRangeKey = new NamespacedKey(customDiscs, "customsoundrange"); + + if(persistentDataContainer.has(customSoundRangeKey, PersistentDataType.FLOAT)) { + range = Math.min(persistentDataContainer.get(customSoundRangeKey, PersistentDataType.FLOAT), CustomDiscs.getInstance().musicDiscMaxDistance); + } + if (discMeta.getJukeboxPlayable().isShowInTooltip()) { JukeboxPlayableComponent jpc = discMeta.getJukeboxPlayable(); jpc.setShowInTooltip(false); @@ -52,24 +70,34 @@ public class HopperManager implements Listener { Path soundFilePath = Path.of(customDiscs.getDataFolder().getPath(), "musicdata", soundFileName); assert VoicePlugin.voicechatServerApi != null; - playerManager.playLocationalAudio(VoicePlugin.voicechatServerApi, soundFilePath, event.getDestination().getLocation().getBlock(), customActionBarSongPlaying); + playerManager.playLocationalAudio(VoicePlugin.voicechatServerApi, soundFilePath, event.getDestination().getLocation().getBlock(), customActionBarSongPlaying, range); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onJukeboxEjectToHopper(InventoryMoveItemEvent event) { + //logger.warning("Enter : onJukeboxEjectToHopper"); + InventoryHolder holderSource = event.getSource().getHolder(); + InventoryHolder holderDestination = event.getDestination().getHolder(); + if (event.getSource().getLocation() == null) return; if (!event.getSource().getType().equals(InventoryType.JUKEBOX)) return; if (event.getItem().getItemMeta() == null) return; if (!isCustomMusicDisc(event.getItem())) return; - event.setCancelled(playerManager.isAudioPlayerPlaying(event.getSource().getLocation())); + if (holderDestination instanceof HopperMinecart) { + discToHopper(((BlockState) holderSource).getBlock()); + stopDiscOnEject(((BlockState) holderSource).getBlock()); + } else { + event.setCancelled(playerManager.isAudioPlayerPlaying(event.getSource().getLocation())); + } + } public void discToHopper(Block block) { - + //logger.warning("Enter : discToHopper"); if (block == null) return; if (!block.getLocation().getChunk().isLoaded()) return; if (!block.getType().equals(Material.JUKEBOX)) return; @@ -85,6 +113,7 @@ public class HopperManager implements Listener { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onChunkLoad(ChunkLoadEvent event) { + //logger.warning("Enter : onChunkLoad"); for (BlockState blockState : event.getChunk().getTileEntities()) { if (blockState instanceof Jukebox jukebox) { if (!jukebox.hasRecord()) return; @@ -98,12 +127,18 @@ public class HopperManager implements Listener { } private boolean isCustomMusicDisc(ItemStack item) { + //logger.warning("Enter : isCustomMusicDisc"); return item.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customdisc"), PersistentDataType.STRING); } + + private void stopDiscOnEject(Block block) { + playerManager.stopLocationalAudio(block.getLocation()); + } private static HopperManager instance; public static HopperManager instance() { + //logger.warning("Enter : HopperManager Instance"); if (instance == null) { instance = new HopperManager(); } diff --git a/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java b/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java index 0d707e2..af11c58 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java +++ b/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java @@ -8,8 +8,8 @@ import de.maxhenkel.voicechat.api.audiochannel.LocationalAudioChannel; import javazoom.spi.mpeg.sampled.convert.MpegFormatConversionProvider; import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -44,7 +44,7 @@ public class PlayerManager { }); } - public void playLocationalAudio(VoicechatServerApi api, Path soundFilePath, Block block, Component actionbarComponent) { + public void playLocationalAudio(VoicechatServerApi api, Path soundFilePath, Block 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)); @@ -52,7 +52,7 @@ public class PlayerManager { if (audioChannel == null) return; audioChannel.setCategory(VoicePlugin.MUSIC_DISC_CATEGORY); - audioChannel.setDistance(CustomDiscs.getInstance().musicDiscDistance); + audioChannel.setDistance(range); AtomicBoolean stopped = new AtomicBoolean(); AtomicReference player = new AtomicReference<>(); @@ -68,7 +68,7 @@ public class PlayerManager { }); 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), CustomDiscs.getInstance().musicDiscDistance); + 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 = playChannel(api, audioChannel, block, soundFilePath, playersInRange); @@ -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) { @@ -113,7 +168,25 @@ public class PlayerManager { Bukkit.getLogger().info("Error Occurred At: " + block.getLocation()); for (ServerPlayer serverPlayer : playersInRange) { Player bukkitPlayer = (Player) serverPlayer.getPlayer(); - bukkitPlayer.sendMessage(ChatColor.RED + "An error has occurred while trying to play this disc."); + bukkitPlayer.sendMessage(NamedTextColor.RED + "An error has occurred while trying to play this disc."); + } + 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; } 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 dbbdf7f..4005d47 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java +++ b/src/main/java/me/Navoei/customdiscsplugin/command/CustomDiscCommand.java @@ -5,8 +5,10 @@ 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 me.Navoei.customdiscsplugin.command.SubCommands.SetRangeSubCommand; +import me.Navoei.customdiscsplugin.command.SubCommands.SetHornCooldownSubCommand; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import org.bukkit.ChatColor; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; @@ -23,6 +25,8 @@ 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); @@ -38,7 +42,7 @@ public class CustomDiscCommand extends CommandAPICommand { } private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { - executor.sendMessage(ChatColor.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 ab9a2c9..1cd63a6 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/CreateSubCommand.java @@ -12,7 +12,6 @@ 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; @@ -28,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; @@ -36,7 +37,7 @@ public class CreateSubCommand extends CommandAPICommand { super("create"); this.plugin = plugin; - this.withFullDescription(ChatColor.GRAY + "Creates a custom music disc."); + this.withFullDescription(NamedTextColor.GRAY + "Creates a custom music disc."); this.withUsage("/customdisc create \"Custom Lore\""); this.withArguments(new StringArgument("filename").replaceSuggestions(ArgumentSuggestions.stringCollection((sender) -> { @@ -60,7 +61,7 @@ public class CreateSubCommand extends CommandAPICommand { } private int onCommandPlayer(Player player, CommandArguments arguments) { - if (!isMusicDisc(player)) { + if (!CustomDiscs.isMusicDisc(player) && !CustomDiscs.isGoatHorn(player)) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_DISC.toString())); return 1; } @@ -90,22 +91,88 @@ 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); + + /*1.21.1 + 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}']" + + "]"; + */ + + String itemCommand = "minecraft:give " + player.getName() + " minecraft:goat_horn[" + + "minecraft:instrument={sound_event:\"intentionally_empty\",use_duration:140,range:256F,description:{\"bold\":false,\"color\":\"gray\",\"italic\":false,\"text\":\"" + song_name + "\",\"underlined\":false}}," + + "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))); @@ -113,7 +180,7 @@ public class CreateSubCommand extends CommandAPICommand { } private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { - executor.sendMessage(ChatColor.RED + "Only players can use this command!"); + executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!"); return 1; } @@ -125,8 +192,4 @@ public class CreateSubCommand extends CommandAPICommand { 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/DownloadSubCommand.java b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java index 21744a1..6acf8c4 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/DownloadSubCommand.java @@ -7,8 +7,8 @@ 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.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; import org.codehaus.plexus.util.FileUtils; @@ -27,7 +27,7 @@ public class DownloadSubCommand extends CommandAPICommand { super("download"); this.plugin = plugin; - this.withFullDescription(ChatColor.GRAY + "Downloads a file from a given URL."); + this.withFullDescription(NamedTextColor.GRAY + "Downloads a file from a given URL."); this.withUsage("/customdisc download "); this.withArguments(new TextArgument("url")); @@ -86,7 +86,7 @@ public class DownloadSubCommand extends CommandAPICommand { } private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) { - executor.sendMessage(ChatColor.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 new file mode 100644 index 0000000..b5fbc1d --- /dev/null +++ b/src/main/java/me/Navoei/customdiscsplugin/command/SubCommands/SetRangeSubCommand.java @@ -0,0 +1,96 @@ +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.Bukkit; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +//import org.bukkit.Material; +import org.bukkit.NamespacedKey; +//import org.bukkit.inventory.ItemFlag; +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 SetRangeSubCommand extends CommandAPICommand { + private final CustomDiscs plugin; + + public SetRangeSubCommand(CustomDiscs plugin) { + super("range"); + this.plugin = plugin; + + this.withFullDescription(NamedTextColor.GRAY + "Set the range of a disc to the defined value (range from 1 to "+ this.plugin.musicDiscMaxDistance +")."); + this.withUsage("/cd range "); + + this.withArguments(new FloatArgument("range")); + + this.executesPlayer(this::onCommandPlayer); + this.executesConsole(this::onCommandConsole); + } + + private int onCommandPlayer(Player player, CommandArguments arguments) { + if (!CustomDiscs.isMusicDisc(player) && !CustomDiscs.isGoatHorn(player)) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_DISC.toString())); + return 1; + } + + if (!player.hasPermission("customdiscs.range")) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString())); + return 1; + } + + Float range = Objects.requireNonNull(arguments.getByClass("range", Float.class)); + + if ( range < 1 || range > this.plugin.musicDiscMaxDistance) { + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_RANGE.toString().replace("%range_value%", Float.toString(this.plugin.musicDiscMaxDistance)))); + 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(); + + 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)))); + + 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/event/JukeBox.java b/src/main/java/me/Navoei/customdiscsplugin/event/JukeBox.java index bf32000..45fa637 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/event/JukeBox.java +++ b/src/main/java/me/Navoei/customdiscsplugin/event/JukeBox.java @@ -10,7 +10,6 @@ import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; -import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.block.Block; @@ -26,6 +25,7 @@ import org.bukkit.event.player.PlayerInteractEvent; 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 java.io.FileNotFoundException; @@ -51,6 +51,15 @@ public class JukeBox implements Listener{ ItemMeta discMeta = event.getItem().getItemMeta(); String soundFileName = discMeta.getPersistentDataContainer().get(new NamespacedKey(customDiscs, "customdisc"), PersistentDataType.STRING); + + PersistentDataContainer persistentDataContainer = event.getItem().getItemMeta().getPersistentDataContainer(); + float range = CustomDiscs.getInstance().musicDiscDistance; + NamespacedKey customSoundRangeKey = new NamespacedKey(customDiscs, "customsoundrange"); + + if(persistentDataContainer.has(customSoundRangeKey, PersistentDataType.FLOAT)) { + range = Math.min(persistentDataContainer.get(customSoundRangeKey, PersistentDataType.FLOAT), CustomDiscs.getInstance().musicDiscMaxDistance); + } + if (discMeta.getJukeboxPlayable().isShowInTooltip()) { JukeboxPlayableComponent jpc = discMeta.getJukeboxPlayable(); jpc.setShowInTooltip(false); @@ -69,9 +78,9 @@ public class JukeBox implements Listener{ Component customActionBarSongPlaying = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.NOW_PLAYING.toString().replace("%song_name%", songName)); assert VoicePlugin.voicechatServerApi != null; - playerManager.playLocationalAudio(VoicePlugin.voicechatServerApi, soundFilePath, block, customActionBarSongPlaying); + playerManager.playLocationalAudio(VoicePlugin.voicechatServerApi, soundFilePath, block, customActionBarSongPlaying, range); } else { - player.sendMessage(ChatColor.RED + "Sound file not found."); + player.sendMessage(NamedTextColor.RED + "Sound file not found."); event.setCancelled(true); throw new FileNotFoundException("Sound file is missing!"); } @@ -143,4 +152,4 @@ public class JukeBox implements Listener{ playerManager.stopLocationalAudio(block.getLocation()); } -} +} \ No newline at end of file diff --git a/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java b/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java index f4e161d..0d8db19 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java +++ b/src/main/java/me/Navoei/customdiscsplugin/language/Lang.java @@ -1,6 +1,5 @@ package me.Navoei.customdiscsplugin.language; -import org.bukkit.ChatColor; import org.bukkit.configuration.file.YamlConfiguration; public enum Lang { @@ -19,7 +18,13 @@ public enum Lang { CREATE_DISC("create-disc", "&aCreate a disc by doing &7/cd create filename.extension \"Custom Lore\"&a."), DOWNLOAD_ERROR("download-error", "&rAn error has occurred while downloading."), 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."); + 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%\"."), + 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 ed57bc6..6823c95 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -3,14 +3,24 @@ # The distance from which music discs can be heard in blocks. music-disc-distance: 16 +# The max distance from which music discs can be heard in blocks. +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]-" - "&aAuthor&7: &6Navoei" + - "&aContributors&7: &6alfw / &6Athar42" - "&fGit&0Hub&7: &9&ohttps://github.com/Navoei/CustomDiscs" \ No newline at end of file diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index c16a00f..0059485 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -15,3 +15,9 @@ create-disc: "&aCreate a disc by doing &7/cd create %filename% \"Custom Lore\"&a download-error: "&cAn error has occurred while downloading." 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 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 8fa365e..39b7482 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ version: '${plugin_version}' main: me.Navoei.customdiscsplugin.CustomDiscs api-version: '${bukkit_api_version}' prefix: CustomDiscs -authors: [ "Navoei" ] +authors: [ "Navoei", "Athar42", "alfw" ] description: A plugin which uses the Simple Voice Chat API to add custom music discs. depend: [ "voicechat", "ProtocolLib" ] dependencies: