From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: syldium Date: Fri, 9 Jul 2021 18:50:40 +0200 Subject: [PATCH] Add more advancement API == AT == public net.minecraft.advancements.Advancement decorateName(Lnet/minecraft/advancements/DisplayInfo;)Lnet/minecraft/network/chat/Component; Co-authored-by: Jake Potrebic diff --git a/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java b/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java new file mode 100644 index 0000000000000000000000000000000000000000..adac21ce6db3ff7a56dbcd6bffc02143c2db4046 --- /dev/null +++ b/src/main/java/io/papermc/paper/advancement/PaperAdvancementDisplay.java @@ -0,0 +1,69 @@ +package io.papermc.paper.advancement; + +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; +import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementType; +import net.minecraft.advancements.DisplayInfo; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public record PaperAdvancementDisplay(DisplayInfo handle) implements AdvancementDisplay { + + @Override + public @NotNull Frame frame() { + return asPaperFrame(this.handle.getType()); + } + + @Override + public @NotNull Component title() { + return PaperAdventure.asAdventure(this.handle.getTitle()); + } + + @Override + public @NotNull Component description() { + return PaperAdventure.asAdventure(this.handle.getDescription()); + } + + @Override + public @NotNull ItemStack icon() { + return CraftItemStack.asBukkitCopy(this.handle.getIcon()); + } + + @Override + public boolean doesShowToast() { + return this.handle.shouldShowToast(); + } + + @Override + public boolean doesAnnounceToChat() { + return this.handle.shouldAnnounceChat(); + } + + @Override + public boolean isHidden() { + return this.handle.isHidden(); + } + + @Override + public @Nullable NamespacedKey backgroundPath() { + return this.handle.getBackground().map(CraftNamespacedKey::fromMinecraft).orElse(null); + } + + @Override + public @NotNull Component displayName() { + return PaperAdventure.asAdventure(Advancement.decorateName(java.util.Objects.requireNonNull(this.handle, "cannot build display name for null handle, invalid state"))); + } + + public static @NotNull Frame asPaperFrame(final @NotNull AdvancementType frameType) { + return switch (frameType) { + case TASK -> Frame.TASK; + case CHALLENGE -> Frame.CHALLENGE; + case GOAL -> Frame.GOAL; + }; + } +} diff --git a/src/main/java/net/minecraft/advancements/DisplayInfo.java b/src/main/java/net/minecraft/advancements/DisplayInfo.java index 05de12414a3ad1c8f0f02f7973898dda84b89b82..6581cdbec730d5d184566e7b611369b3c424fecf 100644 --- a/src/main/java/net/minecraft/advancements/DisplayInfo.java +++ b/src/main/java/net/minecraft/advancements/DisplayInfo.java @@ -37,6 +37,7 @@ public class DisplayInfo { private final boolean hidden; private float x; private float y; + public final io.papermc.paper.advancement.AdvancementDisplay paper = new io.papermc.paper.advancement.PaperAdvancementDisplay(this); // Paper - Add more advancement API public DisplayInfo( ItemStack icon, diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java index 52baf818579a6841b77ff80e42f4f1b9f635ea08..8dfaca2efa0b0bdc97b75aaa83158a2e46361e4e 100644 --- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java +++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java @@ -29,12 +29,47 @@ public class CraftAdvancement implements org.bukkit.advancement.Advancement { return Collections.unmodifiableCollection(this.handle.value().criteria().keySet()); } + // Paper start - Add more advancement API @Override - public AdvancementDisplay getDisplay() { - if (this.handle.value().display().isEmpty()) { - return null; + public io.papermc.paper.advancement.AdvancementDisplay getDisplay() { + return this.handle.value().display().map(d -> d.paper).orElse(null); + } + + @Deprecated + @io.papermc.paper.annotation.DoNotUse + public AdvancementDisplay getDisplay0() { // May be called by plugins via Commodore + return this.handle.value().display().map(CraftAdvancementDisplay::new).orElse(null); + } + + @Override + public net.kyori.adventure.text.Component displayName() { + return io.papermc.paper.adventure.PaperAdventure.asAdventure(net.minecraft.advancements.Advancement.name(this.handle)); + } + + @Override + public org.bukkit.advancement.Advancement getParent() { + return this.handle.value().parent() + .map(net.minecraft.server.MinecraftServer.getServer().getAdvancements()::get) + .map(AdvancementHolder::toBukkit) + .orElse(null); + } + + @Override + public Collection getChildren() { + final com.google.common.collect.ImmutableList.Builder children = com.google.common.collect.ImmutableList.builder(); + final net.minecraft.advancements.AdvancementNode advancementNode = net.minecraft.server.MinecraftServer.getServer().getAdvancements().tree().get(this.handle); + if (advancementNode != null) { + for (final net.minecraft.advancements.AdvancementNode child : advancementNode.children()) { + children.add(child.holder().toBukkit()); + } } + return children.build(); + } - return new CraftAdvancementDisplay(this.handle.value().display().get()); + @Override + public org.bukkit.advancement.Advancement getRoot() { + final net.minecraft.advancements.AdvancementNode advancementNode = net.minecraft.server.MinecraftServer.getServer().getAdvancements().tree().get(this.handle); + return java.util.Objects.requireNonNull(advancementNode, "could not find internal advancement node for advancement " + this.handle.id()).root().holder().toBukkit(); } + // Paper end - Add more advancement API } diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java index 8ca86852319d7463f60832bc98b825b0b4325995..62ada73302c6b3ce3fb2dcc8c31a1d9c0ac4fd09 100644 --- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java +++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java @@ -6,6 +6,7 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.inventory.ItemStack; +@Deprecated // Paper public class CraftAdvancementDisplay implements org.bukkit.advancement.AdvancementDisplay { private final DisplayInfo handle; diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java index 07e3ff72a186165734da56cb0a60138b7b77dc5a..376520f5136dca50a3f35a42bd1f19091df36dfd 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java @@ -433,6 +433,11 @@ public class Commodore { super.visitMethodInsn(opcode, owner, name, "()Lcom/destroystokyo/paper/profile/PlayerProfile;", itf); return; } + if (owner.equals("org/bukkit/advancement/Advancement") && name.equals("getDisplay") && desc.endsWith(")Lorg/bukkit/advancement/AdvancementDisplay;")) { + super.visitTypeInsn(Opcodes.CHECKCAST, runtimeCbPkgPrefix() + "advancement/CraftAdvancement"); + super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, runtimeCbPkgPrefix() + "advancement/CraftAdvancement", "getDisplay0", desc, false); + return; + } // Paper end if (modern) { diff --git a/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java b/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java new file mode 100644 index 0000000000000000000000000000000000000000..47535c27d7cffc4b5ee6cc9e145b1087477eef79 --- /dev/null +++ b/src/test/java/io/papermc/paper/advancement/AdvancementFrameTest.java @@ -0,0 +1,24 @@ +package io.papermc.paper.advancement; + +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.format.TextColor; +import net.minecraft.advancements.AdvancementType; +import net.minecraft.network.chat.contents.TranslatableContents; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class AdvancementFrameTest { + + @Test + public void test() { + for (final AdvancementType advancementType : AdvancementType.values()) { + final TextColor expectedColor = PaperAdventure.asAdventure(advancementType.getChatColor()); + final String expectedTranslationKey = ((TranslatableContents) advancementType.getDisplayName().getContents()).getKey(); + final var frame = PaperAdvancementDisplay.asPaperFrame(advancementType); + assertEquals(expectedTranslationKey, frame.translationKey(), "The translation keys should be the same"); + assertEquals(expectedColor, frame.color(), "The frame colors should be the same"); + assertEquals(advancementType.getSerializedName(), AdvancementDisplay.Frame.NAMES.key(frame)); + } + } +}