mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
Add api to resolve components (#7648)
This commit is contained in:
parent
3c0aa837c1
commit
48d31a56e9
6 changed files with 153 additions and 4 deletions
|
@ -567,7 +567,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
|
||||
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import java.io.IOException;
|
||||
+
|
||||
+/**
|
||||
+ * Paper API-specific methods for working with {@link Component}s and related.
|
||||
|
@ -578,6 +583,66 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Resolves a component with a specific command sender and subject.
|
||||
+ * <p>
|
||||
+ * Note that in Vanilla, elevated permissions are usually required to use
|
||||
+ * '@' selectors in various component types, but this method should not
|
||||
+ * check such permissions from the sender.
|
||||
+ * <p>
|
||||
+ * A {@link CommandSender} argument is required to resolve:
|
||||
+ * <ul>
|
||||
+ * <li>{@link net.kyori.adventure.text.NBTComponent}</li>
|
||||
+ * <li>{@link net.kyori.adventure.text.ScoreComponent}</li>
|
||||
+ * <li>{@link net.kyori.adventure.text.SelectorComponent}</li>
|
||||
+ * </ul>
|
||||
+ * A {@link Entity} argument is optional to help resolve:
|
||||
+ * <ul>
|
||||
+ * <li>{@link net.kyori.adventure.text.ScoreComponent}</li>
|
||||
+ * </ul>
|
||||
+ * {@link net.kyori.adventure.text.TranslatableComponent}s don't require any extra arguments.
|
||||
+ *
|
||||
+ * @param input the component to resolve
|
||||
+ * @param context the command sender to resolve with
|
||||
+ * @param scoreboardSubject the scoreboard subject to use (for use with {@link net.kyori.adventure.text.ScoreComponent}s)
|
||||
+ * @return the resolved component
|
||||
+ * @throws IOException if a syntax error tripped during resolving
|
||||
+ */
|
||||
+ public static @NotNull Component resolveWithContext(@NotNull Component input, @Nullable CommandSender context, @Nullable Entity scoreboardSubject) throws IOException {
|
||||
+ return resolveWithContext(input, context, scoreboardSubject, true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Resolves a component with a specific command sender and subject.
|
||||
+ * <p>
|
||||
+ * Note that in Vanilla, elevated permissions are required to use
|
||||
+ * '@' selectors in various component types. If the boolean {@code bypassPermissions}
|
||||
+ * argument is {@code false}, the {@link CommandSender} argument will be used to query
|
||||
+ * those permissions.
|
||||
+ * <p>
|
||||
+ * A {@link CommandSender} argument is required to resolve:
|
||||
+ * <ul>
|
||||
+ * <li>{@link net.kyori.adventure.text.NBTComponent}</li>
|
||||
+ * <li>{@link net.kyori.adventure.text.ScoreComponent}</li>
|
||||
+ * <li>{@link net.kyori.adventure.text.SelectorComponent}</li>
|
||||
+ * </ul>
|
||||
+ * A {@link Entity} argument is optional to help resolve:
|
||||
+ * <ul>
|
||||
+ * <li>{@link net.kyori.adventure.text.ScoreComponent}</li>
|
||||
+ * </ul>
|
||||
+ * {@link net.kyori.adventure.text.TranslatableComponent}s don't require any extra arguments.
|
||||
+ *
|
||||
+ * @param input the component to resolve
|
||||
+ * @param context the command sender to resolve with
|
||||
+ * @param scoreboardSubject the scoreboard subject to use (for use with {@link net.kyori.adventure.text.ScoreComponent}s)
|
||||
+ * @param bypassPermissions true to bypass permissions checks for resolving components
|
||||
+ * @return the resolved component
|
||||
+ * @throws IOException if a syntax error tripped during resolving
|
||||
+ */
|
||||
+ public static @NotNull Component resolveWithContext(@NotNull Component input, @Nullable CommandSender context, @Nullable Entity scoreboardSubject, boolean bypassPermissions) throws IOException {
|
||||
+ return Bukkit.getUnsafe().resolveWithContext(input, context, scoreboardSubject, bypassPermissions);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Return a component flattener that can use game data to resolve extra information about components.
|
||||
+ *
|
||||
+ * @return a component flattener
|
||||
|
@ -1317,6 +1382,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.gson.GsonComponentSerializer gsonComponentSerializer();
|
||||
+ @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.gson.GsonComponentSerializer colorDownsamplingGsonComponentSerializer();
|
||||
+ @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer();
|
||||
+ net.kyori.adventure.text.Component resolveWithContext(net.kyori.adventure.text.Component component, org.bukkit.command.CommandSender context, org.bukkit.entity.Entity scoreboardSubject, boolean bypassPermissions) throws java.io.IOException;
|
||||
+ // Paper end
|
||||
|
||||
Material toLegacy(Material material);
|
||||
|
|
|
@ -2838,7 +2838,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/org/bukkit/UnsafeValues.java
|
||||
+++ b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
@@ -0,0 +0,0 @@ public interface UnsafeValues {
|
||||
@Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer();
|
||||
net.kyori.adventure.text.Component resolveWithContext(net.kyori.adventure.text.Component component, org.bukkit.command.CommandSender context, org.bukkit.entity.Entity scoreboardSubject, boolean bypassPermissions) throws java.io.IOException;
|
||||
// Paper end
|
||||
|
||||
+ void reportTimings(); // Paper
|
||||
|
|
|
@ -726,17 +726,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+import net.kyori.adventure.translation.Translator;
|
||||
+import net.kyori.adventure.util.Codec;
|
||||
+import net.minecraft.ChatFormatting;
|
||||
+import net.minecraft.commands.CommandSourceStack;
|
||||
+import net.minecraft.locale.Language;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.nbt.ListTag;
|
||||
+import net.minecraft.nbt.StringTag;
|
||||
+import net.minecraft.nbt.TagParser;
|
||||
+import net.minecraft.network.chat.ComponentUtils;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.sounds.SoundSource;
|
||||
+import net.minecraft.world.BossEvent;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.item.WrittenBookItem;
|
||||
+import org.bukkit.ChatColor;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.craftbukkit.command.VanillaCommandWrapper;
|
||||
+import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
|
@ -894,6 +899,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ );
|
||||
+ }
|
||||
+
|
||||
+ public static Component resolveWithContext(final @NotNull Component component, final @Nullable CommandSender context, final @Nullable Entity scoreboardSubject, final boolean bypassPermissions) throws IOException {
|
||||
+ final CommandSourceStack css = context != null ? VanillaCommandWrapper.getListener(context) : null;
|
||||
+ Boolean previous = null;
|
||||
+ if (css != null && bypassPermissions) {
|
||||
+ previous = css.bypassSelectorPermissions;
|
||||
+ css.bypassSelectorPermissions = true;
|
||||
+ }
|
||||
+ try {
|
||||
+ return asAdventure(ComponentUtils.updateForEntity(css, asVanilla(component), scoreboardSubject == null ? null : ((CraftEntity) scoreboardSubject).getHandle(), 0));
|
||||
+ } catch (CommandSyntaxException e) {
|
||||
+ throw new IOException(e);
|
||||
+ } finally {
|
||||
+ if (css != null && previous != null) {
|
||||
+ css.bypassSelectorPermissions = previous;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // BossBar
|
||||
+
|
||||
+ public static BossEvent.BossBarColor asVanilla(final BossBar.Color color) {
|
||||
|
@ -1423,6 +1446,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@Nullable
|
||||
public static ChatFormatting getById(int colorIndex) {
|
||||
if (colorIndex < 0) {
|
||||
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
@@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider {
|
||||
private final CommandSigningContext signingContext;
|
||||
private final TaskChainer chatMessageChainer;
|
||||
public volatile CommandNode currentCommand; // CraftBukkit
|
||||
+ public boolean bypassSelectorPermissions = false; // Paper
|
||||
|
||||
public CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity) {
|
||||
this(output, pos, rot, world, level, name, displayName, server, entity, false, (commandcontext, flag, j) -> {
|
||||
diff --git a/src/main/java/net/minecraft/commands/arguments/MessageArgument.java b/src/main/java/net/minecraft/commands/arguments/MessageArgument.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/arguments/MessageArgument.java
|
||||
|
@ -1445,6 +1480,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
MessageArgument.logResolutionFailure(source, completableFuture);
|
||||
return completableFuture;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
+++ b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
@@ -0,0 +0,0 @@ public class EntitySelector {
|
||||
}
|
||||
|
||||
private void checkPermissions(CommandSourceStack source) throws CommandSyntaxException {
|
||||
- if (this.usesSelector && !source.hasPermission(2, "minecraft.command.selector")) { // CraftBukkit
|
||||
+ if (source.bypassSelectorPermissions || (this.usesSelector && !source.hasPermission(2, "minecraft.command.selector"))) { // CraftBukkit // Paper
|
||||
throw EntityArgument.ERROR_SELECTORS_NOT_ALLOWED.create();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
|
@ -1693,6 +1741,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
JsonObject jsonobject = new JsonObject();
|
||||
|
||||
if (!ichatbasecomponent.getStyle().isEmpty()) {
|
||||
diff --git a/src/main/java/net/minecraft/network/chat/ComponentUtils.java b/src/main/java/net/minecraft/network/chat/ComponentUtils.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/chat/ComponentUtils.java
|
||||
+++ b/src/main/java/net/minecraft/network/chat/ComponentUtils.java
|
||||
@@ -0,0 +0,0 @@ public class ComponentUtils {
|
||||
if (depth > 100) {
|
||||
return text.copy();
|
||||
} else {
|
||||
+ // Paper start
|
||||
+ if (text instanceof io.papermc.paper.adventure.AdventureComponent adventureComponent) {
|
||||
+ text = adventureComponent.deepConverted();
|
||||
+ }
|
||||
+ // Paper end
|
||||
MutableComponent mutableComponent = text.getContents().resolve(source, sender, depth + 1);
|
||||
|
||||
for(Component component : text.getSiblings()) {
|
||||
diff --git a/src/main/java/net/minecraft/network/chat/OutgoingPlayerChatMessage.java b/src/main/java/net/minecraft/network/chat/OutgoingPlayerChatMessage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/chat/OutgoingPlayerChatMessage.java
|
||||
|
@ -4432,6 +4496,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer() {
|
||||
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.Component resolveWithContext(final net.kyori.adventure.text.Component component, final org.bukkit.command.CommandSender context, final org.bukkit.entity.Entity scoreboardSubject, final boolean bypassPermissions) throws IOException {
|
||||
+ return io.papermc.paper.adventure.PaperAdventure.resolveWithContext(component, context, scoreboardSubject, bypassPermissions);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static BlockState getBlock(MaterialData material) {
|
||||
|
|
|
@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2), true); // Paper
|
||||
+ // Paper start
|
||||
+ final boolean permission = object instanceof CommandSourceStack stack
|
||||
+ ? stack.hasPermission(2, "minecraft.command.selector")
|
||||
+ ? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector")
|
||||
+ : icompletionprovider.hasPermission(2);
|
||||
+ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission, true); // Paper
|
||||
+ // Paper end
|
||||
|
|
|
@ -128,6 +128,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private static final int MIN_PROTOCOL_ID = -1;
|
||||
private static final int MAX_PROTOCOL_ID = 2;
|
||||
private static final ConnectionProtocol[] LOOKUP = new ConnectionProtocol[4];
|
||||
diff --git a/src/main/java/net/minecraft/network/chat/ComponentUtils.java b/src/main/java/net/minecraft/network/chat/ComponentUtils.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/chat/ComponentUtils.java
|
||||
+++ b/src/main/java/net/minecraft/network/chat/ComponentUtils.java
|
||||
@@ -0,0 +0,0 @@ public class ComponentUtils {
|
||||
ComponentContents string = text.getContents();
|
||||
if (string instanceof TranslatableContents) {
|
||||
TranslatableContents translatableContents = (TranslatableContents)string;
|
||||
- String string = translatableContents.getKey();
|
||||
- return Language.getInstance().has(string);
|
||||
+ return Language.getInstance().has(translatableContents.getKey()); // Paper - decompile fix
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/resources/RegistryLoader.java b/src/main/java/net/minecraft/resources/RegistryLoader.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/resources/RegistryLoader.java
|
||||
|
|
|
@ -35,9 +35,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private final TaskChainer chatMessageChainer;
|
||||
- public volatile CommandNode currentCommand; // CraftBukkit
|
||||
+ public java.util.Map<Thread, CommandNode> currentCommand = new java.util.concurrent.ConcurrentHashMap<>(); // CraftBukkit // Paper
|
||||
public boolean bypassSelectorPermissions = false; // Paper
|
||||
|
||||
public CommandSourceStack(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String name, Component displayName, MinecraftServer server, @Nullable Entity entity) {
|
||||
this(output, pos, rot, world, level, name, displayName, server, entity, false, (commandcontext, flag, j) -> {
|
||||
@@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy
|
||||
@Override
|
||||
public boolean hasPermission(int level) {
|
||||
|
|
Loading…
Reference in a new issue