diff --git a/pom.xml b/pom.xml
index 804adc0..edd23ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -90,6 +90,15 @@
de.themoep:inventorygui
+
+
+ *
+
+ META-INF/MANIFEST.MF
+ META-INF/maven/**
+
+
+
diff --git a/src/main/java/eu/m724/music_plugin/MusicPlugin.java b/src/main/java/eu/m724/music_plugin/MusicPlugin.java
index 9a234aa..d61b8bd 100644
--- a/src/main/java/eu/m724/music_plugin/MusicPlugin.java
+++ b/src/main/java/eu/m724/music_plugin/MusicPlugin.java
@@ -8,6 +8,7 @@ import eu.m724.music_plugin.audio.storage.Downloader;
import eu.m724.music_plugin.item.ItemEvents;
import eu.m724.music_plugin.item.PmpCommand;
import eu.m724.music_plugin.item.speaker.BlockChecker;
+import eu.m724.music_plugin.library.LibraryStorage;
import net.bramp.ffmpeg.FFmpeg;
import org.bukkit.NamespacedKey;
import org.bukkit.plugin.java.JavaPlugin;
@@ -23,6 +24,7 @@ public final class MusicPlugin extends JavaPlugin {
private static AudioFileStorage AUDIO_FILE_STORAGE;
private static Converter CONVERTER;
private static Downloader DOWNLOADER;
+ private static LibraryStorage LIBRARY_STORAGE;
@Override
public void onEnable() {
@@ -41,14 +43,19 @@ public final class MusicPlugin extends JavaPlugin {
service.registerPlugin(new MyVoicechatPlugin(api -> VOICECHAT_API = api));
var storagePath = getDataFolder().toPath().resolve("storage");
+ var audioStoragePath = storagePath.resolve("audio");
+ var libraryStoragePath = storagePath.resolve("library");
+
try {
- Files.createDirectories(storagePath);
+ Files.createDirectories(audioStoragePath);
+ Files.createDirectories(libraryStoragePath);
} catch (IOException e) {
throw new RuntimeException(e);
}
- AUDIO_FILE_STORAGE = new AudioFileStorage(storagePath);
- DOWNLOADER = new Downloader(storagePath);
+ AUDIO_FILE_STORAGE = new AudioFileStorage(audioStoragePath);
+ DOWNLOADER = new Downloader(audioStoragePath);
+ LIBRARY_STORAGE = new LibraryStorage(libraryStoragePath);
try {
CONVERTER = new Converter(new FFmpeg());
@@ -91,6 +98,10 @@ public final class MusicPlugin extends JavaPlugin {
return DOWNLOADER;
}
+ public static LibraryStorage getLibraryStorage() {
+ return LIBRARY_STORAGE;
+ }
+
public static NamespacedKey getNamespacedKey(String key) {
return new NamespacedKey(INSTANCE, key);
}
diff --git a/src/main/java/eu/m724/music_plugin/TestCommand.java b/src/main/java/eu/m724/music_plugin/TestCommand.java
index 31cdc23..eda2054 100644
--- a/src/main/java/eu/m724/music_plugin/TestCommand.java
+++ b/src/main/java/eu/m724/music_plugin/TestCommand.java
@@ -60,26 +60,21 @@ public class TestCommand implements CommandExecutor {
}
private void testConvert(Player player, String hash, int bitrate) {
- try {
- player.sendMessage("Converting...");
- MusicPlugin.getStorage().convert(MusicPlugin.getConverter(), hash, bitrate).handle((f, ex) -> {
- if (ex != null) {
- ex.printStackTrace();
- player.sendMessage("Error converting. See console for details.");
- } else {
- player.spigot().sendMessage(
- new ComponentBuilder("Converted " + hash.substring(0, 7) + "... to " + bitrate + "bps! Click to play")
- .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Click to play")))
- .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/test play " + hash + " " + bitrate))
- .create()
- );
- }
- return null;
- });
- } catch (IOException e) {
- e.printStackTrace();
- player.sendMessage("Error");
- }
+ player.sendMessage("Converting...");
+ MusicPlugin.getStorage().convert(MusicPlugin.getConverter(), hash, bitrate).handle((f, ex) -> {
+ if (ex != null) {
+ ex.printStackTrace();
+ player.sendMessage("Error converting. See console for details.");
+ } else {
+ player.spigot().sendMessage(
+ new ComponentBuilder("Converted " + hash.substring(0, 7) + "... to " + bitrate + "bps! Click to play")
+ .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Click to play")))
+ .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/test play " + hash + " " + bitrate))
+ .create()
+ );
+ }
+ return null;
+ });
}
private void testPlay(Player player, String hash, int bitrate) {
diff --git a/src/main/java/eu/m724/music_plugin/audio/storage/AudioFileStorage.java b/src/main/java/eu/m724/music_plugin/audio/storage/AudioFileStorage.java
index f90433a..9109f5c 100644
--- a/src/main/java/eu/m724/music_plugin/audio/storage/AudioFileStorage.java
+++ b/src/main/java/eu/m724/music_plugin/audio/storage/AudioFileStorage.java
@@ -41,7 +41,10 @@ public class AudioFileStorage {
}
/**
- * Get an audio file of given original hash and bitrate
+ * Get an audio file of given original hash and bitrate
+ *
+ * WARNING Whether the file exists is not checked.
+ * Do it yourself - simply check if the file exists.
*
* @param hash the hex sha256 hash of the original
* @param bitrate the bitrate in bps like 32000
@@ -77,13 +80,18 @@ public class AudioFileStorage {
* @param bitrate the target bitrate in bps
* @return the future with the new file
*/
- public CompletableFuture convert(Converter converter, String hash, int bitrate) throws IOException {
+ public CompletableFuture convert(Converter converter, String hash, int bitrate) {
var file = get(hash, bitrate);
if (Files.exists(file)) return CompletableFuture.completedFuture(file);
var og = getOriginal(hash);
if (!Files.exists(og)) return null;
- return converter.convert(og, file, bitrate).thenApply(v -> file);
+ // TODO maybe do that in Converter?
+ try {
+ return converter.convert(og, file, bitrate);
+ } catch (IOException e) {
+ return CompletableFuture.failedFuture(e);
+ }
}
}
diff --git a/src/main/java/eu/m724/music_plugin/audio/storage/Downloader.java b/src/main/java/eu/m724/music_plugin/audio/storage/Downloader.java
index 5887699..1dbd43d 100644
--- a/src/main/java/eu/m724/music_plugin/audio/storage/Downloader.java
+++ b/src/main/java/eu/m724/music_plugin/audio/storage/Downloader.java
@@ -34,7 +34,7 @@ public class Downloader {
public CompletableFuture download(URI uri) {
DebugLogger.fine("About to download from %s", uri);
- // TODO fix this. Yes this is the only way. sendAsync doesn't block for some reason. I don't know why.
+ // TODO sendAsync doesn't block for some reason
return CompletableFuture.supplyAsync(() -> {
try (
var client = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build()
diff --git a/src/main/java/eu/m724/music_plugin/item/ItemEvents.java b/src/main/java/eu/m724/music_plugin/item/ItemEvents.java
index 7e62569..24e6415 100644
--- a/src/main/java/eu/m724/music_plugin/item/ItemEvents.java
+++ b/src/main/java/eu/m724/music_plugin/item/ItemEvents.java
@@ -20,7 +20,7 @@ public class ItemEvents implements Listener {
if (event.getItem() == null) return;
- var player = PortableMediaPlayers.get(event.getItem());
+ var player = PortableMediaPlayers.fromItemStack(event.getItem());
if (player == null) return;
System.out.println("A player used");
@@ -31,7 +31,7 @@ public class ItemEvents implements Listener {
player.next();
} else {
System.out.println("no shift + lmb: rpevous song");
- player.prev();
+ player.previous();
}
} else {
if (right) {
@@ -65,7 +65,7 @@ public class ItemEvents implements Listener {
@EventHandler
public void onDrop(PlayerDropItemEvent event) {
- var player = PortableMediaPlayers.get(event.getItemDrop().getItemStack());
+ var player = PortableMediaPlayers.fromItemStack(event.getItemDrop().getItemStack());
if (player == null) return;
System.out.println("A playe rdropped");
@@ -75,7 +75,7 @@ public class ItemEvents implements Listener {
@EventHandler
public void onPickup(EntityPickupItemEvent event) {
- var player = PortableMediaPlayers.get(event.getItem().getItemStack());
+ var player = PortableMediaPlayers.fromItemStack(event.getItem().getItemStack());
if (player == null) return;
System.out.println("A player puckuperd");
@@ -86,7 +86,7 @@ public class ItemEvents implements Listener {
@EventHandler
public void onMove(InventoryMoveItemEvent event) {
if (event.getDestination().getType() == InventoryType.PLAYER) {
- var player = PortableMediaPlayers.get(event.getItem());
+ var player = PortableMediaPlayers.fromItemStack(event.getItem());
if (player == null) return;
System.out.println("A player storaged :((");
diff --git a/src/main/java/eu/m724/music_plugin/item/PmpCommand.java b/src/main/java/eu/m724/music_plugin/item/PmpCommand.java
index 7e1254b..83125c4 100644
--- a/src/main/java/eu/m724/music_plugin/item/PmpCommand.java
+++ b/src/main/java/eu/m724/music_plugin/item/PmpCommand.java
@@ -1,20 +1,19 @@
package eu.m724.music_plugin.item;
-import eu.m724.music_plugin.MusicPlugin;
+import eu.m724.music_plugin.library.Track;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import java.io.IOException;
import java.util.Arrays;
public class PmpCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
var player = (Player) sender;
- var pmp = PortableMediaPlayers.get(player.getInventory().getItemInMainHand());
+ var pmp = PortableMediaPlayers.fromItemStack(player.getInventory().getItemInMainHand());
var action = args.length > 0 ? args[0] : null;
@@ -22,18 +21,7 @@ public class PmpCommand implements CommandExecutor {
if (pmp != null) {
sender.sendMessage("ID: " + pmp.id);
sender.sendMessage("Premium: " + pmp.premium);
-
- var capacityStr = "";
- var h = pmp.storageSeconds % 3600;
- var m = (pmp.storageSeconds - (h * 3600)) % 60;
- var s = pmp.storageSeconds - (h * 3600) - (m * 60);
- if (h > 0) {
- capacityStr += h + "h ";
- }
- capacityStr += m + "m " + s + "s ";
-
- sender.sendMessage("Capacity: " + capacityStr);
-
+ sender.sendMessage("Capacity: " + secondsToHms(pmp.storageSeconds));
sender.sendMessage("Bitrate: %d Kbps".formatted(pmp.audioBitrate / 1000));
}
}
@@ -41,23 +29,57 @@ public class PmpCommand implements CommandExecutor {
if ("create".equals(action)) {
pmp = PortableMediaPlayer.create(args[1].equals("yes"), String.join(" ", Arrays.asList(args).subList(2, args.length)));
player.getInventory().addItem(pmp.getItemStack());
- } else if ("play".equals(action)) {
+ } else if ("add".equals(action)) {
if (pmp != null) {
- var storage = MusicPlugin.getStorage();
+ var library = pmp.getLibrary();
+ library.addTrack(new Track(args[1]));
+
+ player.sendMessage("Added track");
+
+ /*var storage = MusicPlugin.getStorage();
var path = storage.get(args[1], Integer.parseInt(args[2]));
try {
pmp.play(path.toFile());
} catch (IOException e) {
throw new RuntimeException(e);
- }
+ }*/
+ } else {
+ player.sendMessage("You must hold a Portable Music Player");
+ }
+ } else if ("play".equals(action)) {
+ if (pmp != null) {
+ pmp.play();
+ player.sendMessage("Started");
+ } else {
+ player.sendMessage("You must hold a Portable Music Player");
+ }
+ } else if ("skip".equals(action)) {
+ if (pmp != null) {
+ pmp.next();
+ player.sendMessage("Skipped");
} else {
player.sendMessage("You must hold a Portable Music Player");
}
} else {
- player.sendMessage("create | play");
+ player.sendMessage("create | add | play | skip");
}
return true;
}
+
+ private String secondsToHms(int seconds) {
+ var sb = new StringBuilder();
+
+ var hours = seconds / 3600;
+ if (hours > 0) {
+ sb.append(hours).append("h ");
+ seconds = seconds % 3600;
+ }
+
+ sb.append(seconds / 60).append("m ");
+ sb.append(seconds % 60).append("s");
+
+ return sb.toString();
+ }
}
diff --git a/src/main/java/eu/m724/music_plugin/item/PortableMediaPlayer.java b/src/main/java/eu/m724/music_plugin/item/PortableMediaPlayer.java
index 13a7279..c7e9601 100644
--- a/src/main/java/eu/m724/music_plugin/item/PortableMediaPlayer.java
+++ b/src/main/java/eu/m724/music_plugin/item/PortableMediaPlayer.java
@@ -5,37 +5,28 @@ import eu.m724.music_plugin.MusicPlugin;
import eu.m724.music_plugin.audio.player.OpusFilePlayer;
import eu.m724.music_plugin.audio.player.TrackEvent;
import eu.m724.music_plugin.item.speaker.Speaker;
-import net.md_5.bungee.api.ChatColor;
-import org.bukkit.Material;
-import org.bukkit.NamespacedKey;
-import org.bukkit.enchantments.Enchantment;
-import org.bukkit.inventory.ItemFlag;
+import eu.m724.music_plugin.library.Library;
import org.bukkit.inventory.ItemStack;
-import org.bukkit.persistence.PersistentDataType;
-import java.awt.*;
import java.io.File;
import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
+import java.util.concurrent.CompletionException;
import java.util.concurrent.ThreadLocalRandom;
public class PortableMediaPlayer {
- static final NamespacedKey idKey = MusicPlugin.getNamespacedKey("player_id");
- static final NamespacedKey dataKey = MusicPlugin.getNamespacedKey("player_data");
-
+ // TODO getters for all that
public final int id;
- // TODO configurable
+ // TODO make those two configurable
public final int storageSeconds;
public final int audioBitrate;
public final boolean premium;
public final String engraving;
+ private final Library library;
private OpusFilePlayer player; // TODO rename?
- private Speaker> speaker;
+ private Speaker> linkedSpeaker;
PortableMediaPlayer(int id, int storageSeconds, int audioBitrate, boolean premium, String engraving) {
this.id = id;
@@ -43,55 +34,45 @@ public class PortableMediaPlayer {
this.audioBitrate = audioBitrate;
this.premium = premium;
this.engraving = engraving;
+
+ // TODO there should be a better way. Like load if needed?
+ this.library = MusicPlugin.getLibraryStorage().load(id);
}
public static PortableMediaPlayer create(boolean premium, String engraving) {
return new PortableMediaPlayer(ThreadLocalRandom.current().nextInt(), 600, 32000, premium, engraving);
}
- public void setSpeaker(Speaker> speaker) {
- if (speaker.equals(this.speaker))
- return;
-
- if (this.speaker != null) {
- // no need to pause if no need to pause
- this.speaker.setDestroyCallback(c -> {});
- this.speaker.destroy();
- }
-
- speaker.setDestroyCallback(v -> {
- System.out.println("spekar rip");
- if (player != null)
- player.pause();
- this.speaker = null;
+ public void play() {
+ DebugLogger.fine("play() called");
+ library.getPlaying().getPath(audioBitrate).thenAccept(p -> {
+ DebugLogger.finer("accepted");
+ try {
+ play(p.toAbsolutePath().toFile());
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new CompletionException(e);
+ }
});
-
- this.speaker = speaker;
- if (player != null)
- player.setChannel(speaker.getChannel().getAudioChannel());
}
- public void play(File file) throws IOException {
- DebugLogger.finer("pmp play");
- if (speaker == null) return;
+ private void play(File file) throws IOException {
+ DebugLogger.finer("playing a file: %s", file.toString());
+ if (linkedSpeaker == null) return;
- //played = new Track(audioFile);
if (player != null)
player.stop();
- this.player = new OpusFilePlayer(file, speaker.getChannel().getAudioChannel());
+ this.player = new OpusFilePlayer(file, linkedSpeaker.getChannel().getAudioChannel());
player.setOnTrackEvent(event -> {
if (event == TrackEvent.START) {
DebugLogger.finer("I detected track START");
- //played.unpause();
} else if (event == TrackEvent.STOP) {
DebugLogger.finer("I detected track STOP");
- //played.pause();
- //played.hint(played.file.getEncoder().getFrame());
} else if (event == TrackEvent.END) {
DebugLogger.finer("I detected track END");
- //next();
+ next();
}
});
@@ -119,58 +100,46 @@ public class PortableMediaPlayer {
player.stop();
}
- // TODO
- void prev() {
- DebugLogger.fine("pmp previous (does nothing)");
+ void previous() {
+ // TODO seek to beginning
+ if (library.previous() != null)
+ play();
}
- // TODO
void next() {
- System.out.println("pmp next (does nothing)");
+ if (library.next() != null)
+ play();
}
- /* Item functions */
+ /* Getters / Setters */
- public ItemStack getItemStack() {
- var is = new ItemStack(premium ? Material.GOLD_INGOT : Material.IRON_INGOT);
- var meta = is.getItemMeta();
+ public void setSpeaker(Speaker> speaker) {
+ if (speaker.equals(this.linkedSpeaker))
+ return;
- if (premium) {
- var hue = (id & 0xFFFFFF) / (float) 0xFFFFFF;
- var saturation = (id >> 24) & 0xF;
- var color = Color.getHSBColor(hue, 0.84f + saturation / 15.0f, 1.0f);
- meta.setItemName(ChatColor.of(color) + "Portable Music Player");
-
- if (engraving != null)
- meta.setLore(List.of(ChatColor.of(color.darker()) + engraving));
- } else {
- meta.setItemName("Portable Music Player");
-
- if (engraving != null) // custom colors only in premium
- meta.setLore(List.of(ChatColor.GRAY + ChatColor.stripColor(engraving)));
+ if (this.linkedSpeaker != null) {
+ // no need to pause if no need to pause
+ this.linkedSpeaker.setDestroyCallback(c -> {});
+ this.linkedSpeaker.destroy();
}
- meta.addEnchant(Enchantment.UNBREAKING, 1, false);
- meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
- meta.getPersistentDataContainer().set(idKey, PersistentDataType.INTEGER, id);
- meta.getPersistentDataContainer().set(dataKey, PersistentDataType.BYTE_ARRAY, getData());
+ speaker.setDestroyCallback(v -> {
+ DebugLogger.finer("linked speaker destroyed");
+ if (player != null)
+ player.pause();
+ this.linkedSpeaker = null;
+ });
- is.setItemMeta(meta);
-
- return is;
+ this.linkedSpeaker = speaker;
+ if (player != null)
+ player.setChannel(speaker.getChannel().getAudioChannel());
}
- private byte[] getData() {
- var buffer = ByteBuffer.allocate(11 + engraving.length());
- buffer.put((byte) 0); // data format version
- buffer.put((byte) (premium ? 1 : 0));
+ public ItemStack getItemStack() {
+ return PortableMediaPlayers.getItemStack(this);
+ }
- buffer.putShort((short) storageSeconds); // make int if 18 hours is not enough. or store as minutes
- buffer.put((byte) (audioBitrate / 1000));
-
- buffer.put((byte) engraving.length());
- buffer.put(engraving.getBytes(StandardCharsets.UTF_8));
-
- return buffer.array();
+ public Library getLibrary() {
+ return this.library;
}
}
diff --git a/src/main/java/eu/m724/music_plugin/item/PortableMediaPlayers.java b/src/main/java/eu/m724/music_plugin/item/PortableMediaPlayers.java
index feab236..7782ad4 100644
--- a/src/main/java/eu/m724/music_plugin/item/PortableMediaPlayers.java
+++ b/src/main/java/eu/m724/music_plugin/item/PortableMediaPlayers.java
@@ -1,26 +1,36 @@
package eu.m724.music_plugin.item;
+import eu.m724.music_plugin.MusicPlugin;
+import net.md_5.bungee.api.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
+import java.awt.*;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-// This class stores PortableMediaPlayer instances so that there's no hassle of working with a new one every time
public class PortableMediaPlayers {
- private static Map players = new HashMap<>();
+ static final NamespacedKey idKey = MusicPlugin.getNamespacedKey("player_id");
+ static final NamespacedKey dataKey = MusicPlugin.getNamespacedKey("player_data");
- public static PortableMediaPlayer get(Integer id) {
+ private static final Map players = new HashMap<>();
+
+ public static PortableMediaPlayer fromId(Integer id) {
return players.get(id);
}
- public static PortableMediaPlayer get(ItemStack itemStack) {
+ public static PortableMediaPlayer fromItemStack(ItemStack itemStack) {
var meta = itemStack.getItemMeta();
if (meta == null) return null;
- var id = meta.getPersistentDataContainer().get(PortableMediaPlayer.idKey, PersistentDataType.INTEGER);
+ var id = meta.getPersistentDataContainer().get(idKey, PersistentDataType.INTEGER);
if (id == null) return null;
// check cache
@@ -30,7 +40,7 @@ public class PortableMediaPlayers {
// if not cached
- var data = meta.getPersistentDataContainer().get(PortableMediaPlayer.dataKey, PersistentDataType.BYTE_ARRAY);
+ var data = meta.getPersistentDataContainer().get(dataKey, PersistentDataType.BYTE_ARRAY);
if (data == null) return null;
player = fromData(id, data);
@@ -57,4 +67,47 @@ public class PortableMediaPlayers {
return new PortableMediaPlayer(id, storageSeconds, audioBitrate, premium, engraving);
}
+
+ private static byte[] getData(PortableMediaPlayer player) {
+ var buffer = ByteBuffer.allocate(11 + player.engraving.length());
+ buffer.put((byte) 0); // data format version
+ buffer.put((byte) (player.premium ? 1 : 0));
+
+ buffer.putShort((short) player.storageSeconds); // make int if 18 hours is not enough. or store as minutes
+ buffer.put((byte) (player.audioBitrate / 1000));
+
+ buffer.put((byte) player.engraving.length());
+ buffer.put(player.engraving.getBytes(StandardCharsets.UTF_8));
+
+ return buffer.array();
+ }
+
+ public static ItemStack getItemStack(PortableMediaPlayer player) {
+ var is = new ItemStack(player.premium ? Material.GOLD_INGOT : Material.IRON_INGOT);
+ var meta = is.getItemMeta();
+
+ if (player.premium) {
+ var hue = (player.id & 0xFFFFFF) / (float) 0xFFFFFF;
+ var saturation = (player.id >> 24) & 0xF;
+ var color = Color.getHSBColor(hue, 0.84f + saturation / 15.0f, 1.0f);
+ meta.setItemName(ChatColor.of(color) + "Portable Music Player");
+
+ if (player.engraving != null)
+ meta.setLore(java.util.List.of(ChatColor.of(color.darker()) + player.engraving));
+ } else {
+ meta.setItemName("Portable Music Player");
+
+ if (player.engraving != null) // custom colors only in premium
+ meta.setLore(List.of(ChatColor.GRAY + ChatColor.stripColor(player.engraving)));
+ }
+
+ meta.addEnchant(Enchantment.UNBREAKING, 1, false);
+ meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
+ meta.getPersistentDataContainer().set(idKey, PersistentDataType.INTEGER, player.id);
+ meta.getPersistentDataContainer().set(dataKey, PersistentDataType.BYTE_ARRAY, getData(player));
+
+ is.setItemMeta(meta);
+
+ return is;
+ }
}
diff --git a/src/main/java/eu/m724/music_plugin/library/Library.java b/src/main/java/eu/m724/music_plugin/library/Library.java
index 643159d..bb59d93 100644
--- a/src/main/java/eu/m724/music_plugin/library/Library.java
+++ b/src/main/java/eu/m724/music_plugin/library/Library.java
@@ -1,13 +1,21 @@
package eu.m724.music_plugin.library;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class Library {
- private List