From ec4076f2ba4f1eb7af1f070629fbb583c6092cad Mon Sep 17 00:00:00 2001 From: Navoei Date: Tue, 9 Aug 2022 22:36:06 -0500 Subject: [PATCH] Volume controls and music disc range Feature update. --- gradle.properties | 4 +- .../Navoei/customdiscsplugin/CustomDiscs.java | 12 ++-- .../customdiscsplugin/PlayerManager.java | 45 +++++++++++--- .../Navoei/customdiscsplugin/VoicePlugin.java | 57 ++++++++++++++++-- .../customdiscsplugin/event/JukeBox.java | 1 - src/main/resources/config.yml | 8 ++- src/main/resources/music_disc_category.png | Bin 0 -> 200 bytes 7 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 src/main/resources/music_disc_category.png diff --git a/gradle.properties b/gradle.properties index 16a386a..2a53a51 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,8 +9,8 @@ bukkit_version=1.19-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.2.39 +voicechat_api_version=2.3.3 -plugin_version=2.0 +plugin_version=2.1 maven_group=me.Navoei.customdiscsplugin archives_base_name=custom-discs \ No newline at end of file diff --git a/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java b/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java index 86dfad3..040ff75 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java +++ b/src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java @@ -18,6 +18,7 @@ import org.bukkit.plugin.java.JavaPlugin; import javax.annotation.Nullable; import java.io.File; +import java.util.Objects; public final class CustomDiscs extends JavaPlugin { @@ -28,6 +29,9 @@ public final class CustomDiscs extends JavaPlugin { @Nullable private VoicePlugin voicechatPlugin; + public float musicDiscDistance; + public float musicDiscVolume; + @Override public void onEnable() { @@ -37,10 +41,7 @@ public final class CustomDiscs extends JavaPlugin { CustomDisc command = new CustomDisc(); - if (!new File(this.getDataFolder(), "config.yml").exists()) { - this.getConfig().options().copyDefaults(true); - } - this.saveConfig(); + this.saveDefaultConfig(); File musicData = new File(this.getDataFolder(), "musicdata"); if (!(musicData.exists())) { @@ -59,6 +60,9 @@ public final class CustomDiscs extends JavaPlugin { getServer().getPluginManager().registerEvents(new HopperManager(), this); getCommand("customdisc").setExecutor(command); + 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) { diff --git a/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java b/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java index 70c5b26..b441142 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java +++ b/src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java @@ -13,10 +13,7 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import javax.annotation.Nullable; -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioInputStream; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.UnsupportedAudioFileException; +import javax.sound.sampled.*; import java.io.IOException; import java.nio.file.Path; import java.util.Map; @@ -49,6 +46,9 @@ public class PlayerManager { if (audioChannel == null) return; + audioChannel.setCategory(VoicePlugin.MUSIC_DISC_CATEGORY); + audioChannel.setDistance(CustomDiscs.getInstance().musicDiscDistance); + AtomicBoolean stopped = new AtomicBoolean(); AtomicReference player = new AtomicReference<>(); @@ -103,11 +103,11 @@ public class PlayerManager { } } - private static short[] readSoundFile(Path file) throws UnsupportedAudioFileException, IOException { + private static short[] readSoundFile(Path file) throws UnsupportedAudioFileException, IOException, LineUnavailableException { return VoicePlugin.voicechatApi.getAudioConverter().bytesToShorts(convertFormat(file, FORMAT)); } - private static byte[] convertFormat(Path file, AudioFormat audioFormat) throws UnsupportedAudioFileException, IOException { + private static byte[] convertFormat(Path file, AudioFormat audioFormat) throws UnsupportedAudioFileException, IOException, LineUnavailableException { AudioInputStream finalInputStream = null; if (getFileExtension(file.toFile().toString()).equals("wav")) { @@ -124,9 +124,38 @@ public class PlayerManager { } assert finalInputStream != null; - return finalInputStream.readAllBytes(); + + return adjustVolume(finalInputStream.readAllBytes(), CustomDiscs.getInstance().musicDiscVolume); } + private static byte[] adjustVolume(byte[] audioSamples, double volume) { + + if (volume > 1d || volume < 0d) { + CustomDiscs.getInstance().getServer().getLogger().info("Error: The volume must be between 0 and 1 in the config!"); + return null; + } + + byte[] array = new byte[audioSamples.length]; + for (int i = 0; i < array.length; i+=2) { + // convert byte pair to int + short buf1 = audioSamples[i+1]; + short buf2 = audioSamples[i]; + + buf1 = (short) ((buf1 & 0xff) << 8); + buf2 = (short) (buf2 & 0xff); + + short res= (short) (buf1 | buf2); + res = (short) (res * volume); + + // convert back + array[i] = (byte) res; + array[i+1] = (byte) (res >> 8); + + } + return array; + } + + public void stopLocationalAudio(Location blockLocation) { UUID id = UUID.nameUUIDFromBytes(blockLocation.toString().getBytes()); Stoppable player = playerMap.get(id); @@ -136,7 +165,7 @@ public class PlayerManager { playerMap.remove(id); } - public static float getLengthSeconds(Path file) throws UnsupportedAudioFileException, IOException { + public static float getLengthSeconds(Path file) throws UnsupportedAudioFileException, IOException, LineUnavailableException { short[] audio = readSoundFile(file); return (float) audio.length / FORMAT.getSampleRate(); } diff --git a/src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java b/src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java index 710402e..5e86208 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java +++ b/src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java @@ -3,17 +3,25 @@ package me.Navoei.customdiscsplugin; import de.maxhenkel.voicechat.api.VoicechatApi; import de.maxhenkel.voicechat.api.VoicechatPlugin; import de.maxhenkel.voicechat.api.VoicechatServerApi; +import de.maxhenkel.voicechat.api.VolumeCategory; import de.maxhenkel.voicechat.api.events.EventRegistration; import de.maxhenkel.voicechat.api.events.VoicechatServerStartedEvent; import javax.annotation.Nullable; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.net.URL; +import java.util.Enumeration; public class VoicePlugin implements VoicechatPlugin { - public static VoicechatApi voicechatApi; + public static String MUSIC_DISC_CATEGORY = "music_discs"; + public static VoicechatApi voicechatApi; @Nullable public static VoicechatServerApi voicechatServerApi; + @Nullable + public static VolumeCategory musicDiscs; /** * @return the unique ID for this voice chat plugin @@ -29,8 +37,8 @@ public class VoicePlugin implements VoicechatPlugin { * @param api the voice chat API */ @Override - public void initialize(final VoicechatApi api) { - VoicePlugin.voicechatApi = api; + public void initialize(VoicechatApi api) { + voicechatApi = api; } /** @@ -39,11 +47,48 @@ public class VoicePlugin implements VoicechatPlugin { * @param registration the event registration */ @Override - public void registerEvents(final EventRegistration registration) { + public void registerEvents(EventRegistration registration) { registration.registerEvent(VoicechatServerStartedEvent.class, this::onServerStarted); } - public void onServerStarted(final VoicechatServerStartedEvent event) { - VoicePlugin.voicechatServerApi = event.getVoicechat(); + public void onServerStarted(VoicechatServerStartedEvent event) { + voicechatServerApi = event.getVoicechat(); + + musicDiscs = voicechatServerApi.volumeCategoryBuilder() + .setId(MUSIC_DISC_CATEGORY) + .setName("Music Discs") + .setDescription("The volume of music discs") + .setIcon(getMusicDiscIcon()) + .build(); + voicechatServerApi.registerVolumeCategory(musicDiscs); + } + + private int[][] getMusicDiscIcon() { + try { + Enumeration resources = CustomDiscs.getInstance().getClass().getClassLoader().getResources("music_disc_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; + } + } diff --git a/src/main/java/me/Navoei/customdiscsplugin/event/JukeBox.java b/src/main/java/me/Navoei/customdiscsplugin/event/JukeBox.java index bd705f7..8849f8e 100644 --- a/src/main/java/me/Navoei/customdiscsplugin/event/JukeBox.java +++ b/src/main/java/me/Navoei/customdiscsplugin/event/JukeBox.java @@ -27,7 +27,6 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Path; import java.util.Objects; -import java.util.UUID; public class JukeBox implements Listener{ diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2c1da75..0e1e60c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1 +1,7 @@ -#Might add config options in the future. \ No newline at end of file +# [Music Disc Config] + +# The distance from which music discs can be heard in blocks. +music-disc-distance: 16 + +# The master volume of music discs from 0-1. (You can set values like 0.5 for 50% volume). +music-disc-volume: 1 \ No newline at end of file diff --git a/src/main/resources/music_disc_category.png b/src/main/resources/music_disc_category.png new file mode 100644 index 0000000000000000000000000000000000000000..84ae70e8d0f99ec58cb9da009cb1565bbb8bab93 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`{hlt4Ar_~T6C~z21O|Szw^H+* z+}zB}b}U=M%(trG8f z4PrkU$sHEpVZOj?7$x-2{@)5|iR8~*U5pB|FZ}J7VSDkAIjCQVuc@gi!BOIv825=! x3ST7*8HHLBQ;wdPl`tb=mP44&mSqdM8Jf=>$#*;dHyr3R22WQ%mvv4FO#m#bN8A7a literal 0 HcmV?d00001