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 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..b9c24b8d83b96d8c66cdf879650027f40eafb274 --- /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.DisplayInfo; +import net.minecraft.advancements.FrameType; +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.getFrame()); + } + + @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() == null ? null : CraftNamespacedKey.fromMinecraft(this.handle.getBackground()); + } + + @Override + public @NotNull Component displayName() { + return PaperAdventure.asAdventure(Advancement.constructDisplayComponent(null, this.handle)); + } + + public static @NotNull Frame asPaperFrame(@NotNull FrameType 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/Advancement.java b/src/main/java/net/minecraft/advancements/Advancement.java index 72e09d3472af376b1b7aa50c3d9ab3d837a2bed3..81359be381fc9bcb56a9cc83e70a6afa6e838c6a 100644 --- a/src/main/java/net/minecraft/advancements/Advancement.java +++ b/src/main/java/net/minecraft/advancements/Advancement.java @@ -55,8 +55,16 @@ public class Advancement { parent.addChild(this); } - if (display == null) { - this.chatComponent = Component.literal(id.toString()); + // Paper start - moved to static method + this.chatComponent = constructDisplayComponent(this.id, this.display); + } + + public static Component constructDisplayComponent(final @Nullable ResourceLocation id, final @Nullable DisplayInfo display) { + if (id == null && display == null) { + throw new IllegalArgumentException("can't both be null"); + } else if (display == null) { + return Component.literal(id.toString()); + // Paper end } else { Component ichatbasecomponent = display.getTitle(); ChatFormatting enumchatformat = display.getFrame().getChatColor(); @@ -65,7 +73,7 @@ public class Advancement { return chatmodifier.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, ichatmutablecomponent)); }); - this.chatComponent = ComponentUtils.wrapInSquareBrackets(ichatmutablecomponent1).withStyle(enumchatformat); + return ComponentUtils.wrapInSquareBrackets(ichatmutablecomponent1).withStyle(enumchatformat); // Paper } } diff --git a/src/main/java/net/minecraft/advancements/DisplayInfo.java b/src/main/java/net/minecraft/advancements/DisplayInfo.java index 2e9e8b1f391a223cfb0fed9a100ae78004ad2f48..7909ba26bb7a883c74eda1ffd2d3e2bad286bc8b 100644 --- a/src/main/java/net/minecraft/advancements/DisplayInfo.java +++ b/src/main/java/net/minecraft/advancements/DisplayInfo.java @@ -28,6 +28,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 public DisplayInfo(ItemStack icon, Component title, Component description, @Nullable ResourceLocation background, FrameType frame, boolean showToast, boolean announceToChat, boolean hidden) { this.title = title; diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java index c47cae84f3b6970247d78382f48ae8ddbc202b59..1435251a4fb721b800e6a1f07b50c5f743e04081 100644 --- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java +++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java @@ -29,12 +29,43 @@ public class CraftAdvancement implements org.bukkit.advancement.Advancement { return Collections.unmodifiableCollection(this.handle.getCriteria().keySet()); } + // Paper start @Override - public AdvancementDisplay getDisplay() { - if (this.handle.getDisplay() == null) { - return null; + public io.papermc.paper.advancement.AdvancementDisplay getDisplay() { + return this.handle.getDisplay() == null ? null : this.handle.getDisplay().paper; + } + + @Deprecated @io.papermc.paper.annotation.DoNotUse + public AdvancementDisplay getDisplay0() { // May be called by plugins via Commodore + return this.handle.getDisplay() == null ? null : new CraftAdvancementDisplay(this.handle.getDisplay()); + } + + @Override + public net.kyori.adventure.text.Component displayName() { + return io.papermc.paper.adventure.PaperAdventure.asAdventure(Advancement.constructDisplayComponent(this.handle.getId(), this.handle.getDisplay())); + } + + @Override + public org.bukkit.advancement.Advancement getParent() { + return this.handle.getParent() == null ? null : this.handle.getParent().bukkit; + } + + @Override + public Collection getChildren() { + final var children = com.google.common.collect.ImmutableList.builder(); + for (Advancement advancement : this.handle.getChildren()) { + children.add(advancement.bukkit); } + return children.build(); + } - return new CraftAdvancementDisplay(this.handle.getDisplay()); + @Override + public org.bukkit.advancement.Advancement getRoot() { + Advancement advancement = this.handle; + while (advancement.getParent() != null) { + advancement = advancement.getParent(); + } + return advancement.bukkit; } + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementDisplay.java index 4aa8cda2bf72627b153e636a408fb3971caf2309..e29d7c6e1cef10a76c8630855fada11cee583d30 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 2500ca4cda59d16285c1749669ea21fddaf14f53..ef28f880a4f603a48be5b32acc697f567a78b963 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java @@ -151,6 +151,7 @@ public class Commodore { } // Paper start - Plugin rewrites + private static final String CB_PACKAGE = org.bukkit.Bukkit.getServer().getClass().getPackageName().replace('.', '/'); private static final java.util.Map SEARCH_AND_REMOVE = initReplacementsMap(); private static java.util.Map initReplacementsMap() { java.util.Map getAndRemove = new java.util.HashMap<>(); @@ -918,6 +919,13 @@ public class Commodore { return; } // Paper end + // Paper start - advancement API + if (owner.equals("org/bukkit/advancement/Advancement") && name.equals("getDisplay") && desc.endsWith(")Lorg/bukkit/advancement/AdvancementDisplay;")) { + super.visitTypeInsn(Opcodes.CHECKCAST, CB_PACKAGE + "/advancement/CraftAdvancement"); + super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CB_PACKAGE + "/advancement/CraftAdvancement", "getDisplay0", desc, false); + return; + } + // Paper end if (modern) { if (owner.equals("org/bukkit/Material")) { switch (name) { 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..4d043e0e43ef8bb75788e195f95b5a50a51a2a48 --- /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.FrameType; +import net.minecraft.network.chat.contents.TranslatableContents; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class AdvancementFrameTest { + + @Test + public void test() { + for (FrameType nmsFrameType : FrameType.values()) { + final TextColor expectedColor = PaperAdventure.asAdventure(nmsFrameType.getChatColor()); + final String expectedTranslationKey = ((TranslatableContents) nmsFrameType.getDisplayName().getContents()).getKey(); + final var frame = PaperAdvancementDisplay.asPaperFrame(nmsFrameType); + assertEquals("The translation keys should be the same", expectedTranslationKey, frame.translationKey()); + assertEquals("The frame colors should be the same", expectedColor, frame.color()); + assertEquals(nmsFrameType.getName(), AdvancementDisplay.Frame.NAMES.key(frame)); + } + } +}