mirror of
https://github.com/SPAWNRYS-ban/FUCK-CustomDiscs.git
synced 2025-12-10 21:40:13 +05:00
Better Async Tasks
Now using a BukkitRunnable and a Map to determine if an async task is running. This allows the plugin to prevent the jukebox from being modified before the task is complete, which prevents the jukebox from bugging out and causing discs to be lost.
This commit is contained in:
@@ -11,6 +11,6 @@ mod_id=customdiscsplugin
|
||||
# Target an older API to make it compatible with older versions of Simple Voice Chat
|
||||
voicechat_api_version=2.2.22
|
||||
|
||||
plugin_version=1.3
|
||||
plugin_version=1.3.1
|
||||
maven_group=me.Navoei.customdiscsplugin
|
||||
archives_base_name=custom-discs
|
||||
@@ -26,6 +26,7 @@ import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
@@ -40,6 +41,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class JukeBox implements Listener{
|
||||
|
||||
private final Map<UUID, AudioPlayer> playerMap = new ConcurrentHashMap<>();
|
||||
private final Map<Location, BukkitRunnable> asyncTaskMap = new ConcurrentHashMap<>();
|
||||
public static AudioFormat FORMAT = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 48000F, 16, 1, 2, 48000F, false);
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
@@ -57,7 +59,7 @@ public class JukeBox implements Listener{
|
||||
"CustomDisc");
|
||||
if (container.has(key, PersistentDataType.BYTE_ARRAY)) {
|
||||
event.setCancelled(true);
|
||||
ejectDisc(block);
|
||||
ejectDisc(block, player);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,11 +67,11 @@ public class JukeBox implements Listener{
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
UUID id = UUID.nameUUIDFromBytes(block.getLocation().toString().getBytes());
|
||||
|
||||
Component soundFileNameComponent = Objects.requireNonNull(event.getItem().getItemMeta().lore()).get(1).asComponent();
|
||||
String soundFileName = PlainTextComponentSerializer.plainText().serialize(soundFileNameComponent);
|
||||
|
||||
UUID id = UUID.nameUUIDFromBytes(block.getLocation().toString().getBytes());
|
||||
|
||||
Path soundFilePath = Path.of(CustomDiscs.getInstance().getDataFolder().getPath(), "musicdata", soundFileName);
|
||||
|
||||
if (soundFilePath.toFile().exists()) {
|
||||
@@ -80,9 +82,12 @@ public class JukeBox implements Listener{
|
||||
LocationalAudioChannel audioChannel = VoicePlugin.voicechatServerApi.createLocationalAudioChannel(id, VoicePlugin.voicechatApi.fromServerLevel(block.getLocation().getWorld()), VoicePlugin.voicechatApi.createPosition(block.getLocation().getX() + 0.5d, block.getLocation().getY() + 0.5d, block.getLocation().getZ() + 0.5d));
|
||||
|
||||
//Run the audio player asynchronously to prevent lag when inserting discs.
|
||||
Bukkit.getScheduler().runTaskAsynchronously(CustomDiscs.getInstance(), () -> {
|
||||
AudioPlayer audioPlayer = null;
|
||||
//Put the task in a hashmap to be able to access it later.
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//Try playing the voice chat audio player.
|
||||
AudioPlayer audioPlayer = null;
|
||||
try {
|
||||
audioPlayer = VoicePlugin.voicechatServerApi.createAudioPlayer(audioChannel, VoicePlugin.voicechatApi.createEncoder(), readSoundFile(soundFilePath));
|
||||
} catch (UnsupportedAudioFileException | IOException e) {
|
||||
@@ -94,12 +99,7 @@ public class JukeBox implements Listener{
|
||||
assert audioPlayer != null;
|
||||
audioPlayer.startPlaying();
|
||||
|
||||
//Run this in sync with the main thread after the disc is done loading.
|
||||
Bukkit.getScheduler().runTask(CustomDiscs.getInstance(), () -> {
|
||||
//set the persistent data container
|
||||
container.set(key, PersistentDataType.BYTE_ARRAY, event.getItem().serializeAsBytes());
|
||||
tileState.update();
|
||||
|
||||
//Send Player Action Bar
|
||||
TextComponent customLoreSong = Component.text()
|
||||
.content("Now Playing: " + songName)
|
||||
@@ -108,7 +108,23 @@ public class JukeBox implements Listener{
|
||||
player.sendActionBar(customLoreSong.asComponent());
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
asyncTaskMap.put(block.getLocation(), runnable);
|
||||
asyncTaskMap.get(block.getLocation()).runTaskAsynchronously(CustomDiscs.getInstance());
|
||||
|
||||
//Send Player Action Bar
|
||||
TextComponent customLoadingSong = Component.text()
|
||||
.content("Loading Disc...")
|
||||
.color(NamedTextColor.GRAY)
|
||||
.build();
|
||||
player.sendActionBar(customLoadingSong.asComponent());
|
||||
|
||||
//set the persistent data container
|
||||
container.set(key, PersistentDataType.BYTE_ARRAY, event.getItem().serializeAsBytes());
|
||||
tileState.update();
|
||||
|
||||
//Remove the item from the player's hand in sync to prevent players from glitching the jukebox.
|
||||
player.getInventory().setItem(Objects.requireNonNull(event.getHand()), null);
|
||||
|
||||
@@ -130,55 +146,37 @@ public class JukeBox implements Listener{
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getClickedBlock() == null || block == null) return;
|
||||
if (event.getClickedBlock().getType() != Material.JUKEBOX) return;
|
||||
|
||||
UUID id = UUID.nameUUIDFromBytes(block.getLocation().toString().getBytes());
|
||||
|
||||
//Spawn in item at the block position
|
||||
TileState tileState = (TileState) block.getState();
|
||||
PersistentDataContainer container = tileState.getPersistentDataContainer();
|
||||
NamespacedKey key = new NamespacedKey(CustomDiscs.getInstance(),
|
||||
"CustomDisc");
|
||||
if (!container.has(key, PersistentDataType.BYTE_ARRAY)) return;
|
||||
container.get(key, PersistentDataType.BYTE_ARRAY);
|
||||
|
||||
Location dropItemLocation = new Location(block.getWorld(), block.getLocation().getX(), block.getLocation().getY()+0.5d, block.getLocation().getZ());
|
||||
|
||||
block.getWorld().dropItemNaturally(dropItemLocation, ItemStack.deserializeBytes(container.get(key, PersistentDataType.BYTE_ARRAY)));
|
||||
|
||||
container.remove(key);
|
||||
tileState.update();
|
||||
|
||||
player.swingMainHand();
|
||||
|
||||
if (isAudioPlayerPlaying(playerMap, id)) {
|
||||
stopAudioPlayer(playerMap, id);
|
||||
if (isAsyncTaskRunning(asyncTaskMap, block.getLocation())) {
|
||||
//Send Player Action Bar
|
||||
TextComponent songLoading = Component.text()
|
||||
.content("Disc is currently loading!")
|
||||
.color(NamedTextColor.RED)
|
||||
.build();
|
||||
player.sendActionBar(songLoading.asComponent());
|
||||
event.setCancelled(true);
|
||||
} else {
|
||||
ejectDisc(block, player);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onJukeboxBreak(BlockBreakEvent event) {
|
||||
|
||||
Block block = event.getBlock();
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (block.getType() != Material.JUKEBOX) return;
|
||||
|
||||
UUID id = UUID.nameUUIDFromBytes(block.getLocation().toString().getBytes());
|
||||
|
||||
//Spawn in item at the block position
|
||||
TileState tileState = (TileState) block.getState();
|
||||
PersistentDataContainer container = tileState.getPersistentDataContainer();
|
||||
NamespacedKey key = new NamespacedKey(CustomDiscs.getInstance(),
|
||||
"CustomDisc");
|
||||
if (!container.has(key, PersistentDataType.BYTE_ARRAY)) return;
|
||||
container.get(key, PersistentDataType.BYTE_ARRAY);
|
||||
|
||||
block.getWorld().dropItemNaturally(block.getLocation(), ItemStack.deserializeBytes(container.get(key, PersistentDataType.BYTE_ARRAY)));
|
||||
|
||||
container.remove(key);
|
||||
tileState.update();
|
||||
|
||||
if (isAudioPlayerPlaying(playerMap, id)) {
|
||||
stopAudioPlayer(playerMap, id);
|
||||
if (isAsyncTaskRunning(asyncTaskMap, block.getLocation())) {
|
||||
//Send Player Action Bar
|
||||
TextComponent songLoading = Component.text()
|
||||
.content("Disc is currently loading!")
|
||||
.color(NamedTextColor.RED)
|
||||
.build();
|
||||
player.sendActionBar(songLoading.asComponent());
|
||||
event.setCancelled(true);
|
||||
} else {
|
||||
ejectDisc(block, player);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -189,34 +187,16 @@ public class JukeBox implements Listener{
|
||||
for (Block explodedBlock : event.blockList()) {
|
||||
if (explodedBlock.getType() == Material.JUKEBOX) {
|
||||
|
||||
UUID id = UUID.nameUUIDFromBytes(explodedBlock.getLocation().toString().getBytes());
|
||||
|
||||
//Spawn in item at the block position
|
||||
TileState tileState = (TileState) explodedBlock.getState();
|
||||
PersistentDataContainer container = tileState.getPersistentDataContainer();
|
||||
NamespacedKey key = new NamespacedKey(CustomDiscs.getInstance(),
|
||||
"CustomDisc");
|
||||
if (!container.has(key, PersistentDataType.BYTE_ARRAY)) return;
|
||||
container.get(key, PersistentDataType.BYTE_ARRAY);
|
||||
|
||||
explodedBlock.getWorld().dropItemNaturally(explodedBlock.getLocation(), ItemStack.deserializeBytes(container.get(key, PersistentDataType.BYTE_ARRAY)));
|
||||
|
||||
container.remove(key);
|
||||
tileState.update();
|
||||
|
||||
if (isAudioPlayerPlaying(playerMap, id)) {
|
||||
stopAudioPlayer(playerMap, id);
|
||||
if (isAsyncTaskRunning(asyncTaskMap, explodedBlock.getLocation())) {
|
||||
event.setCancelled(true);
|
||||
} else {
|
||||
ejectDisc(explodedBlock, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isAudioPlayerPlaying(Map<UUID, AudioPlayer> playerMap, UUID id) {
|
||||
AudioPlayer audioPlayer = playerMap.get(id);
|
||||
if (audioPlayer == null) return false;
|
||||
return audioPlayer.isPlaying();
|
||||
}
|
||||
|
||||
private boolean jukeboxContainsPersistentData(Block b) {
|
||||
TileState tileState = (TileState) b.getState();
|
||||
@@ -282,8 +262,7 @@ public class JukeBox implements Listener{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Might Replace some code with this:
|
||||
private void ejectDisc(Block block) {
|
||||
private void ejectDisc(Block block, Player player) {
|
||||
UUID id = UUID.nameUUIDFromBytes(block.getLocation().toString().getBytes());
|
||||
|
||||
//Spawn in item at the block position
|
||||
@@ -294,7 +273,7 @@ public class JukeBox implements Listener{
|
||||
if (!container.has(key, PersistentDataType.BYTE_ARRAY)) return;
|
||||
container.get(key, PersistentDataType.BYTE_ARRAY);
|
||||
|
||||
block.getWorld().dropItemNaturally(block.getLocation(), ItemStack.deserializeBytes(container.get(key, PersistentDataType.BYTE_ARRAY)));
|
||||
block.getWorld().dropItemNaturally(block.getLocation().add(0.0, 0.5, 0.0), ItemStack.deserializeBytes(container.get(key, PersistentDataType.BYTE_ARRAY)));
|
||||
|
||||
container.remove(key);
|
||||
tileState.update();
|
||||
@@ -302,6 +281,17 @@ public class JukeBox implements Listener{
|
||||
if (isAudioPlayerPlaying(playerMap, id)) {
|
||||
stopAudioPlayer(playerMap, id);
|
||||
}
|
||||
|
||||
asyncTaskMap.remove(block.getLocation());
|
||||
|
||||
if (player == null) return;
|
||||
player.swingMainHand();
|
||||
}
|
||||
|
||||
public boolean isAudioPlayerPlaying(Map<UUID, AudioPlayer> playerMap, UUID id) {
|
||||
AudioPlayer audioPlayer = playerMap.get(id);
|
||||
if (audioPlayer == null) return false;
|
||||
return audioPlayer.isPlaying();
|
||||
}
|
||||
|
||||
private void stopAudioPlayer(Map<UUID, AudioPlayer> playerMap, UUID id) {
|
||||
@@ -309,6 +299,14 @@ public class JukeBox implements Listener{
|
||||
if (audioPlayer != null && audioPlayer.isPlaying()) {
|
||||
audioPlayer.stopPlaying();
|
||||
}
|
||||
playerMap.remove(id);
|
||||
}
|
||||
|
||||
public boolean isAsyncTaskRunning(Map<Location, BukkitRunnable> asyncTaskMap, Location blockLocation) {
|
||||
if (!asyncTaskMap.containsKey(blockLocation)) return false;
|
||||
int taskId = asyncTaskMap.get(blockLocation).getTaskId();
|
||||
System.out.println("Task is currently:" + Bukkit.getScheduler().isCurrentlyRunning(taskId) + " Task#" + taskId);
|
||||
return Bukkit.getScheduler().isCurrentlyRunning(taskId);
|
||||
}
|
||||
|
||||
private static String getFileExtension(String s) {
|
||||
|
||||
Reference in New Issue
Block a user