From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 28 Jun 2020 19:27:20 -0400
Subject: [PATCH] Paper dumpitem command

Let's you quickly view the item in your hands NBT data

diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java
index 25f6d1c15cdfb4abdf1edd2ad9bbdc0e37b546f3..d2536f4ffae721f4df714b5345fa3329c3b8e3f5 100644
--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
@@ -1,6 +1,7 @@
 package io.papermc.paper.command;
 
 import io.papermc.paper.command.subcommands.ChunkDebugCommand;
+import io.papermc.paper.command.subcommands.DumpItemCommand;
 import io.papermc.paper.command.subcommands.EntityCommand;
 import io.papermc.paper.command.subcommands.FixLightCommand;
 import io.papermc.paper.command.subcommands.HeapDumpCommand;
@@ -46,6 +47,7 @@ public final class PaperCommand extends Command {
         commands.put(Set.of("debug", "chunkinfo"), new ChunkDebugCommand());
         commands.put(Set.of("fixlight"), new FixLightCommand());
         commands.put(Set.of("syncloadinfo"), new SyncLoadInfoCommand());
+        commands.put(Set.of("dumpitem"), new DumpItemCommand());
 
         return commands.entrySet().stream()
             .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
diff --git a/src/main/java/io/papermc/paper/command/subcommands/DumpItemCommand.java b/src/main/java/io/papermc/paper/command/subcommands/DumpItemCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..771503ff637fea10d4d8be0f37f3f146c41791d9
--- /dev/null
+++ b/src/main/java/io/papermc/paper/command/subcommands/DumpItemCommand.java
@@ -0,0 +1,59 @@
+package io.papermc.paper.command.subcommands;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import io.papermc.paper.command.PaperSubcommand;
+import java.util.Objects;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.event.ClickEvent;
+import net.minecraft.core.Registry;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.world.item.ItemStack;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.entity.Player;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.checkerframework.framework.qual.DefaultQualifier;
+
+import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.YELLOW;
+import static net.kyori.adventure.text.format.TextDecoration.ITALIC;
+
+@DefaultQualifier(NonNull.class)
+public final class DumpItemCommand implements PaperSubcommand {
+    @Override
+    public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
+        this.doDumpItem(sender);
+        return true;
+    }
+
+    private void doDumpItem(final CommandSender sender) {
+        if (!(sender instanceof Player)) {
+            sender.sendMessage("Only players can use this command");
+            return;
+        }
+        final ItemStack itemStack = CraftItemStack.asNMSCopy(((CraftPlayer) sender).getItemInHand());
+        final @Nullable CompoundTag tag = itemStack.getTag();
+        final @Nullable Component nbtComponent = tag == null ? null : PaperAdventure.asAdventure(net.minecraft.nbt.NbtUtils.toPrettyComponent(tag));
+        final String itemId = Objects.requireNonNull(((CraftWorld) ((CraftPlayer) sender).getWorld()).getHandle().registryAccess()
+            .registryOrThrow(Registry.ITEM_REGISTRY).getKey(itemStack.getItem())).toString();
+        final Component message = text()
+            .append(text(itemId, YELLOW))
+            .apply(b -> {
+                if (nbtComponent != null) {
+                    b.append(nbtComponent);
+                }
+            })
+            .build();
+        Bukkit.getConsoleSender().sendMessage(message);
+        sender.sendMessage(message);
+        sender.sendMessage(text().content("    Click to copy item to clipboard")
+            .color(GRAY)
+            .decorate(ITALIC)
+            .clickEvent(ClickEvent.copyToClipboard(tag == null ? itemId : (itemId + tag))));
+    }
+}
