Volume controls and music disc range

Feature update.
This commit is contained in:
Navoei
2022-08-09 22:36:06 -05:00
parent 9460719e01
commit ec4076f2ba
7 changed files with 105 additions and 22 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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<de.maxhenkel.voicechat.api.audiochannel.AudioPlayer> 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();
}

View File

@@ -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<URL> 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;
}
}

View File

@@ -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{

View File

@@ -1 +1,7 @@
#Might add config options in the future.
# [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

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B