From 3d53d7a0231519da681b1000a833f685d31ed667 Mon Sep 17 00:00:00 2001 From: ChomeNS <95471003+ChomeNS@users.noreply.github.com> Date: Fri, 13 Oct 2023 08:34:24 +0700 Subject: [PATCH] music load from item very useful i think i'm the first to do this --- .../chomens_bot/commands/MusicCommand.java | 72 ++++++++++++++++++- .../plugins/MusicPlayerPlugin.java | 17 +++++ .../chomens_bot/song/SongLoaderThread.java | 19 ++++- 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/MusicCommand.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/MusicCommand.java index e98cbd95..7f0e053f 100644 --- a/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/MusicCommand.java +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/MusicCommand.java @@ -1,5 +1,7 @@ package land.chipmunk.chayapak.chomens_bot.commands; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; import land.chipmunk.chayapak.chomens_bot.Bot; import land.chipmunk.chayapak.chomens_bot.Main; import land.chipmunk.chayapak.chomens_bot.command.Command; @@ -11,14 +13,14 @@ import land.chipmunk.chayapak.chomens_bot.song.Instrument; import land.chipmunk.chayapak.chomens_bot.song.Loop; import land.chipmunk.chayapak.chomens_bot.song.Note; import land.chipmunk.chayapak.chomens_bot.song.Song; -import land.chipmunk.chayapak.chomens_bot.util.ColorUtilities; -import land.chipmunk.chayapak.chomens_bot.util.PathUtilities; -import land.chipmunk.chayapak.chomens_bot.util.TimestampUtilities; +import land.chipmunk.chayapak.chomens_bot.util.*; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.JoinConfiguration; +import net.kyori.adventure.text.TranslatableComponent; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import java.io.IOException; import java.net.MalformedURLException; @@ -26,7 +28,9 @@ import java.net.URI; import java.nio.file.*; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; public class MusicCommand extends Command { @@ -74,6 +78,7 @@ public class MusicCommand extends Command { root = MusicPlayerPlugin.SONG_DIR; return switch (action) { case "play", "playurl", "playnbs", "playnbsurl" -> play(context); + case "playfromitem", "playitem" -> playFromItem(context); case "stop" -> stop(context); case "loop" -> loop(context); case "list" -> list(context); @@ -190,6 +195,67 @@ public class MusicCommand extends Command { return null; } + public Component playFromItem (CommandContext context) throws CommandException { + // mail command lol + + final Bot bot = context.bot; + + final CompletableFuture future = bot.core.runTracked( + "minecraft:data get entity " + + UUIDUtilities.selector(context.sender.profile.getId()) + + " SelectedItem.tag.data" + ); + + if (future == null) { + throw new CommandException(Component.text("There was an error while getting your data")); + } + + future.thenApply(tags -> { + if (!tags.contains("LastOutput") || !(tags.get("LastOutput") instanceof StringTag)) return tags; + + final StringTag lastOutput = tags.get("LastOutput"); + + final Component output = GsonComponentSerializer.gson().deserialize(lastOutput.getValue()); + + final List children = output.children(); + + if ( + !children.isEmpty() && + !children.get(0).children().isEmpty() && + ((TranslatableComponent) children.get(0).children().get(0)) + .key() + .equals("arguments.nbtpath.nothing_found") + ) { + context.sendOutput(Component.text("Player has no `data` NBT tag in the selected item").color(NamedTextColor.RED)); + return tags; + } + + final String value = ComponentUtilities.stringify(((TranslatableComponent) children.get(0)).args().get(1)); + + if (!value.startsWith("\"") && !value.endsWith("\"") && !value.startsWith("'") && !value.endsWith("'")) { + context.sendOutput(Component.text("`data` NBT is not a string").color(NamedTextColor.RED)); + return tags; + } + + try { + bot.music.loadSong( + Base64.getDecoder().decode( + value + .substring(1) + .substring(0, value.length() - 2) + ), + context.sender + ); + } catch (IllegalArgumentException e) { + context.sendOutput(Component.text("Invalid base64 in the selected item").color(NamedTextColor.RED)); + } + + return tags; + }); + + return null; + } + public Component stop (CommandContext context) { final Bot bot = context.bot; bot.music.stopPlaying(); diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/MusicPlayerPlugin.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/MusicPlayerPlugin.java index 84ec96ad..b904ac6d 100644 --- a/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/MusicPlayerPlugin.java +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/MusicPlayerPlugin.java @@ -114,6 +114,23 @@ public class MusicPlayerPlugin extends Bot.Listener { loaderThread.start(); } + public void loadSong (byte[] data, PlayerEntry sender) { + if (songQueue.size() > 100) return; + + loaderThread = new SongLoaderThread(data, bot, sender.profile.getName()); + + bot.chat.tellraw( + Component + .translatable( + "Loading %s", + Component.text(sender.profile.getName() + "'s song item", ColorUtilities.getColorByString(bot.config.colorPalette.secondary)) + ) + .color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor)) + ); + + loaderThread.start(); + } + public void coreReady () { bot.tick.addListener(new TickPlugin.Listener() { @Override diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/song/SongLoaderThread.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/song/SongLoaderThread.java index a5231dac..e82cd522 100644 --- a/src/main/java/land/chipmunk/chayapak/chomens_bot/song/SongLoaderThread.java +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/song/SongLoaderThread.java @@ -40,6 +40,10 @@ public class SongLoaderThread extends Thread { private final boolean isUrl; + private byte[] data; + + private boolean isItem = false; + private boolean isFolder = false; public SongLoaderThread(URL location, Bot bot, String requester) { @@ -62,9 +66,19 @@ public class SongLoaderThread extends Thread { fileName = location.getFileName().toString(); } + public SongLoaderThread (byte[] data, Bot bot, String requester) { + this.bot = bot; + this.requester = requester; + this.data = data; + this.isItem = true; + this.isUrl = false; + + fileName = requester + "'s song item"; + } + @Override public void run () { - if (isFolder && !isUrl) { + if (isFolder && !isUrl && !isItem) { try (Stream files = Files.list(songPath)) { if (files != null) { files.forEach((file) -> { @@ -91,6 +105,9 @@ public class SongLoaderThread extends Thread { final Path fileName = Paths.get(songUrl.toURI().getPath()).getFileName(); name = fileName == null ? "(root)" : fileName.toString(); + } else if (isItem) { + bytes = data; + name = requester + "'s song item"; } else { bytes = Files.readAllBytes(songPath); name = !isFolder ? fileName : songPath.getFileName().toString();