This commit is contained in:
Bjarne Koll 2024-06-14 11:59:44 +02:00
parent 8a6e31ec59
commit 7289589315
32 changed files with 19 additions and 272 deletions

View file

@ -2152,7 +2152,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ resultNodes.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains( ":" )); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below + resultNodes.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains( ":" )); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below
Iterator iterator = tree.getChildren().iterator(); Iterator iterator = tree.getChildren().iterator();
boolean registeredAskServerSuggestionsForTree = false; // Paper - tell clients to ask server for suggestions for EntityArguments while (iterator.hasNext()) {
@@ -0,0 +0,0 @@ public class Commands { @@ -0,0 +0,0 @@ public class Commands {
if (commandnode2.canUse(source)) { if (commandnode2.canUse(source)) {
@ -2222,7 +2222,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public int autosavePeriod; public int autosavePeriod;
- public Commands vanillaCommandDispatcher; - public Commands vanillaCommandDispatcher;
+ // Paper - don't store the vanilla dispatcher + // Paper - don't store the vanilla dispatcher
public boolean forceTicks; // Paper private boolean forceTicks;
// CraftBukkit end // CraftBukkit end
// Spigot start // Spigot start
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@ -2396,7 +2396,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected final DedicatedServer console; protected final DedicatedServer console;
protected final DedicatedPlayerList playerList; protected final DedicatedPlayerList playerList;
@@ -0,0 +0,0 @@ public final class CraftServer implements Server { @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
this.serverTickManager = new CraftServerTickManager(console.tickRateManager()); this.serverLinks = new CraftServerLinks(console);
Bukkit.setServer(this); Bukkit.setServer(this);
+ // Paper start + // Paper start

View file

@ -22,7 +22,7 @@ diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileSto
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { @@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException {
RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit
@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (nbt == null) { if (nbt == null) {
regionfile.clear(pos); regionfile.clear(pos);
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { @@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
dataoutputstream.close(); dataoutputstream.close();
} }
} }

View file

@ -125,7 +125,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper start // Paper start
@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
&& (this.hasTool() ? that.hasTool() && this.tool.equals(that.tool) : !that.hasTool()) && (this.hasJukeboxPlayable() ? that.hasJukeboxPlayable() && this.jukebox.equals(that.jukebox) : !that.hasJukeboxPlayable())
&& (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage()) && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage())
&& (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage()) && (this.hasMaxDamage() ? that.hasMaxDamage() && this.maxDamage.equals(that.maxDamage) : !that.hasMaxDamage())
+ && (this.canPlaceOnPredicates != null ? that.canPlaceOnPredicates != null && this.canPlaceOnPredicates.equals(that.canPlaceOnPredicates) : that.canPlaceOnPredicates == null) // Paper + && (this.canPlaceOnPredicates != null ? that.canPlaceOnPredicates != null && this.canPlaceOnPredicates.equals(that.canPlaceOnPredicates) : that.canPlaceOnPredicates == null) // Paper

View file

@ -15,8 +15,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING)); this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
Entity entity = damagesource.getDirectEntity(); Entity entity = damagesource.getDirectEntity();
- if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance - if (entity instanceof LivingEntity) {
+ if (!damagesource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance + if (!damagesource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity) { // Paper - Fix shield disable inconsistency
this.blockUsingShield((LivingEntity) entity); this.blockUsingShield((LivingEntity) entity);
} }
} }

View file

@ -926,8 +926,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override @Override
public FoodComponent getFood() { public FoodComponent getFood() {
- return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodProperties(0, 0, false, 0, Collections.emptyList())); - return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodProperties(0, 0, false, 0, Optional.empty(), Collections.emptyList()));
+ return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodProperties(0, 0, false, FoodProperties.DEFAULT_EAT_SECONDS, Collections.emptyList())); // Paper - create a valid food properties + return (this.hasFood()) ? new CraftFoodComponent(this.food) : new CraftFoodComponent(new FoodProperties(0, 0, false, FoodProperties.DEFAULT_EAT_SECONDS, Optional.empty(), Collections.emptyList())); // Paper - create a valid food properties
} }
@Override @Override
@ -955,7 +955,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.checkAttributeList(); - this.checkAttributeList();
+ if (this.attributeModifiers != null) { // Paper + if (this.attributeModifiers != null) { // Paper
for (Map.Entry<Attribute, AttributeModifier> entry : this.attributeModifiers.entries()) { for (Map.Entry<Attribute, AttributeModifier> entry : this.attributeModifiers.entries()) {
Preconditions.checkArgument(!(entry.getValue().getUniqueId().equals(modifier.getUniqueId()) && entry.getKey() == attribute), "Cannot register AttributeModifier. Modifier is already applied! %s", modifier); // Paper Preconditions.checkArgument(!entry.getValue().getKey().equals(modifier.getKey()) && entry.getKey() == attribute, "Cannot register AttributeModifier. Modifier is already applied! %s", modifier); // Paper - attribute modifiers with same namespaced key but on different attributes are fine
} }
+ } // Paper + } // Paper
+ this.checkAttributeList(); // Paper - moved down + this.checkAttributeList(); // Paper - moved down
@ -1062,8 +1062,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
&& (Objects.equals(this.customTag, that.customTag)) && (Objects.equals(this.customTag, that.customTag))
&& (this.persistentDataContainer.equals(that.persistentDataContainer)) && (this.persistentDataContainer.equals(that.persistentDataContainer))
@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
hash = 61 * hash + (this.hasFood() ? this.food.hashCode() : 0);
hash = 61 * hash + (this.hasTool() ? this.tool.hashCode() : 0); hash = 61 * hash + (this.hasTool() ? this.tool.hashCode() : 0);
hash = 61 * hash + (this.hasJukeboxPlayable() ? this.jukebox.hashCode() : 0);
hash = 61 * hash + (this.hasDamage() ? this.damage : 0); hash = 61 * hash + (this.hasDamage() ? this.damage : 0);
- hash = 61 * hash + (this.hasMaxDamage() ? 1231 : 1237); - hash = 61 * hash + (this.hasMaxDamage() ? 1231 : 1237);
- hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0); - hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0);
@ -1433,7 +1433,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override @Override
public void setEatSeconds(float eatSeconds) { public void setEatSeconds(float eatSeconds) {
+ Preconditions.checkArgument(eatSeconds > 0, "Eat seconds must be positive"); // Paper - validate eat_seconds + Preconditions.checkArgument(eatSeconds > 0, "Eat seconds must be positive"); // Paper - validate eat_seconds
this.handle = new FoodProperties(this.handle.nutrition(), this.handle.saturation(), this.handle.canAlwaysEat(), eatSeconds, this.handle.effects()); this.handle = new FoodProperties(this.handle.nutrition(), this.handle.saturation(), this.handle.canAlwaysEat(), eatSeconds, this.handle.usingConvertsTo(), this.handle.effects());
} }
@@ -0,0 +0,0 @@ public final class CraftFoodComponent implements FoodComponent { @@ -0,0 +0,0 @@ public final class CraftFoodComponent implements FoodComponent {

View file

@ -47,7 +47,7 @@ diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileSto
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { @@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
try { try {
NbtIo.write(nbt, (DataOutput) dataoutputstream); NbtIo.write(nbt, (DataOutput) dataoutputstream);
@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} catch (Throwable throwable1) { } catch (Throwable throwable1) {
throwable.addSuppressed(throwable1); throwable.addSuppressed(throwable1);
} }
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { @@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
throw throwable; throw throwable;
} }
@ -78,7 +78,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
// Paper start - Chunk save reattempt // Paper start - Chunk save reattempt
return; return;
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { @@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
public RegionStorageInfo info() { public RegionStorageInfo info() {
return this.info; return this.info;
} }

View file

@ -14,7 +14,7 @@ diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileSto
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable { @@ -0,0 +0,0 @@ public final class RegionFileStorage implements AutoCloseable {
if (regionfile != null) { if (regionfile != null) {
return regionfile; return regionfile;
} else { } else {

View file

@ -460,6 +460,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- CraftMetaItem.RARITY.TYPE, - CraftMetaItem.RARITY.TYPE,
- CraftMetaItem.FOOD.TYPE, - CraftMetaItem.FOOD.TYPE,
- CraftMetaItem.TOOL.TYPE, - CraftMetaItem.TOOL.TYPE,
- CraftMetaItem.JUKEBOX_PLAYABLE.TYPE,
- CraftMetaItem.DAMAGE.TYPE, - CraftMetaItem.DAMAGE.TYPE,
- CraftMetaItem.MAX_DAMAGE.TYPE, - CraftMetaItem.MAX_DAMAGE.TYPE,
- CraftMetaItem.CUSTOM_DATA.TYPE, - CraftMetaItem.CUSTOM_DATA.TYPE,
@ -519,6 +520,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ CraftMetaItem.RARITY.TYPE, + CraftMetaItem.RARITY.TYPE,
+ CraftMetaItem.FOOD.TYPE, + CraftMetaItem.FOOD.TYPE,
+ CraftMetaItem.TOOL.TYPE, + CraftMetaItem.TOOL.TYPE,
+ CraftMetaItem.JUKEBOX_PLAYABLE.TYPE,
+ CraftMetaItem.DAMAGE.TYPE, + CraftMetaItem.DAMAGE.TYPE,
+ CraftMetaItem.MAX_DAMAGE.TYPE, + CraftMetaItem.MAX_DAMAGE.TYPE,
+ CraftMetaItem.CUSTOM_DATA.TYPE, + CraftMetaItem.CUSTOM_DATA.TYPE,

View file

@ -1,255 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 26 Apr 2024 23:15:27 -0700
Subject: [PATCH] Add experimental improved give command
Supports removing data components from itemstacks
diff --git a/src/main/java/net/minecraft/commands/arguments/item/ItemArgument.java b/src/main/java/net/minecraft/commands/arguments/item/ItemArgument.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/commands/arguments/item/ItemArgument.java
+++ b/src/main/java/net/minecraft/commands/arguments/item/ItemArgument.java
@@ -0,0 +0,0 @@ public class ItemArgument implements ArgumentType<ItemInput> {
private final ItemParser parser;
public ItemArgument(CommandBuildContext commandRegistryAccess) {
- this.parser = new ItemParser(commandRegistryAccess);
+ // Paper start - support component removals
+ this(commandRegistryAccess, false);
+ }
+ public ItemArgument(CommandBuildContext commandRegistryAccess, boolean allowRemovals) {
+ this.parser = new ItemParser(commandRegistryAccess, allowRemovals);
+ // Paper end - support component removals
}
public static ItemArgument item(CommandBuildContext commandRegistryAccess) {
@@ -0,0 +0,0 @@ public class ItemArgument implements ArgumentType<ItemInput> {
public ItemInput parse(StringReader stringReader) throws CommandSyntaxException {
ItemParser.ItemResult itemResult = this.parser.parse(stringReader);
- return new ItemInput(itemResult.item(), itemResult.components());
+ return new ItemInput(itemResult.item(), itemResult.components(), itemResult.patch()); // Paper - support component removals
}
public static <S> ItemInput getItem(CommandContext<S> context, String name) {
diff --git a/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java b/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java
+++ b/src/main/java/net/minecraft/commands/arguments/item/ItemInput.java
@@ -0,0 +0,0 @@ public class ItemInput {
);
private final Holder<Item> item;
private final DataComponentMap components;
+ @javax.annotation.Nullable private final net.minecraft.core.component.DataComponentPatch patch; // Paper
public ItemInput(Holder<Item> item, DataComponentMap components) {
+ // Paper start
+ this(item, components, null);
+ }
+ public ItemInput(Holder<Item> item, DataComponentMap components, @javax.annotation.Nullable final net.minecraft.core.component.DataComponentPatch patch) {
+ this.patch = patch;
+ // Paper end
this.item = item;
this.components = components;
}
@@ -0,0 +0,0 @@ public class ItemInput {
public ItemStack createItemStack(int amount, boolean checkOverstack) throws CommandSyntaxException {
ItemStack itemStack = new ItemStack(this.item, amount);
- itemStack.applyComponents(this.components);
+ // Paper start - support component removals
+ if (this.patch != null) {
+ itemStack.applyComponents(this.patch);
+ } else {
+ itemStack.applyComponents(this.components);
+ }
+ // Paper end - support component removals
if (checkOverstack && amount > itemStack.getMaxStackSize()) {
throw ERROR_STACK_TOO_BIG.create(this.getItemName(), itemStack.getMaxStackSize());
} else {
diff --git a/src/main/java/net/minecraft/commands/arguments/item/ItemParser.java b/src/main/java/net/minecraft/commands/arguments/item/ItemParser.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/commands/arguments/item/ItemParser.java
+++ b/src/main/java/net/minecraft/commands/arguments/item/ItemParser.java
@@ -0,0 +0,0 @@ public class ItemParser {
static final Function<SuggestionsBuilder, CompletableFuture<Suggestions>> SUGGEST_NOTHING = SuggestionsBuilder::buildFuture;
final HolderLookup.RegistryLookup<Item> items;
final DynamicOps<Tag> registryOps;
+ final boolean allowRemoves; // Paper - support component removals
public ItemParser(HolderLookup.Provider registriesLookup) {
+ // Paper start - support component removals
+ this(registriesLookup, false);
+ }
+ public ItemParser(HolderLookup.Provider registriesLookup, boolean allowRemoves) {
+ this.allowRemoves = allowRemoves;
+ // Paper end - support component removals
this.items = registriesLookup.lookupOrThrow(Registries.ITEM);
this.registryOps = registriesLookup.createSerializationContext(NbtOps.INSTANCE);
}
@@ -0,0 +0,0 @@ public class ItemParser {
public ItemParser.ItemResult parse(StringReader reader) throws CommandSyntaxException {
final MutableObject<Holder<Item>> mutableObject = new MutableObject<>();
final DataComponentMap.Builder builder = DataComponentMap.builder();
+ final net.minecraft.core.component.DataComponentPatch.Builder patchBuilder = net.minecraft.core.component.DataComponentPatch.builder(); // Paper - support component removals
this.parse(reader, new ItemParser.Visitor() {
@Override
public void visitItem(Holder<Item> item) {
@@ -0,0 +0,0 @@ public class ItemParser {
@Override
public <T> void visitComponent(DataComponentType<T> type, T value) {
builder.set(type, value);
+ // Paper start - support component removals
+ patchBuilder.set(type, value);
+ }
+ @Override
+ public <T> void visitComponentRemove(final DataComponentType<T> type) {
+ patchBuilder.remove(type);
+ // Paper end - support component removals
}
});
Holder<Item> holder = Objects.requireNonNull(mutableObject.getValue(), "Parser gave no item");
DataComponentMap dataComponentMap = builder.build();
validateComponents(reader, holder, dataComponentMap);
- return new ItemParser.ItemResult(holder, dataComponentMap);
+ return new ItemParser.ItemResult(holder, dataComponentMap, this.allowRemoves ? patchBuilder.build() : null); // Paper - support component removals
}
private static void validateComponents(StringReader reader, Holder<Item> item, DataComponentMap components) throws CommandSyntaxException {
@@ -0,0 +0,0 @@ public class ItemParser {
return suggestionsVisitor.resolveSuggestions(builder, stringReader);
}
- public static record ItemResult(Holder<Item> item, DataComponentMap components) {
+ public static record ItemResult(Holder<Item> item, DataComponentMap components, @javax.annotation.Nullable net.minecraft.core.component.DataComponentPatch patch) { // Paper
}
class State {
@@ -0,0 +0,0 @@ public class ItemParser {
while (this.reader.canRead() && this.reader.peek() != ']') {
this.reader.skipWhitespace();
+ boolean removing = ItemParser.this.allowRemoves && this.reader.canRead() && this.reader.peek() == '!';
+ if (removing) {
+ this.reader.skip();
+ this.visitor.visitSuggestions(builder -> this.suggestComponentAssignment(builder, false));
+ }
DataComponentType<?> dataComponentType = readComponentType(this.reader);
if (!set.add(dataComponentType)) {
throw ItemParser.ERROR_REPEATED_COMPONENT.create(dataComponentType);
}
+ // Paper start - support component removals
+ if (removing) {
+ this.visitor.visitComponentRemove(dataComponentType);
+ } else {
+ // Paper end - support component removals
this.visitor.visitSuggestions(this::suggestAssignment);
this.reader.skipWhitespace();
this.reader.expect('=');
this.visitor.visitSuggestions(ItemParser.SUGGEST_NOTHING);
this.reader.skipWhitespace();
this.readComponent(dataComponentType);
+ } // Paper - support component removals
this.reader.skipWhitespace();
this.visitor.visitSuggestions(this::suggestNextOrEndComponents);
if (!this.reader.canRead() || this.reader.peek() != ',') {
@@ -0,0 +0,0 @@ public class ItemParser {
}
private CompletableFuture<Suggestions> suggestComponentAssignment(SuggestionsBuilder builder) {
+ // Paper start - support component removals
+ return this.suggestComponentAssignment(builder, true);
+ }
+ private CompletableFuture<Suggestions> suggestComponentAssignment(SuggestionsBuilder builder, boolean suggestRemove) {
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
+ if (suggestRemove && string.isBlank()) builder.suggest("!", Component.literal("Remove a data component"));
+ // Paper end - support component removals
SharedSuggestionProvider.filterResources(BuiltInRegistries.DATA_COMPONENT_TYPE.entrySet(), string, entry -> entry.getKey().location(), entry -> {
DataComponentType<?> dataComponentType = entry.getValue();
if (dataComponentType.codec() != null) {
ResourceLocation resourceLocation = entry.getKey().location();
- builder.suggest(resourceLocation.toString() + "=");
+ builder.suggest(resourceLocation.toString() + (suggestRemove ? "=" : "")); // Paper - support component removals
}
});
return builder.buildFuture();
@@ -0,0 +0,0 @@ public class ItemParser {
default <T> void visitComponent(DataComponentType<T> type, T value) {
}
+ default <T> void visitComponentRemove(DataComponentType<T> type) {} // Paper
default void visitSuggestions(Function<SuggestionsBuilder, CompletableFuture<Suggestions>> suggestor) {
}
diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/commands/GiveCommand.java
+++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java
@@ -0,0 +0,0 @@ public class GiveCommand {
})).then(net.minecraft.commands.Commands.argument("count", IntegerArgumentType.integer(1)).executes((commandcontext) -> {
return GiveCommand.giveItem((CommandSourceStack) commandcontext.getSource(), ItemArgument.getItem(commandcontext, "item"), EntityArgument.getPlayers(commandcontext, "targets"), IntegerArgumentType.getInteger(commandcontext, "count"));
})))));
+ // Paper start - support component removals with a custom pgive command
+ final com.mojang.brigadier.tree.CommandNode<net.minecraft.commands.CommandSourceStack> node = net.minecraft.commands.Commands
+ .literal("pgive").requires((css) -> css.hasPermission(2))
+ .then(net.minecraft.commands.Commands.argument("targets", EntityArgument.players())
+ .then(net.minecraft.commands.Commands.argument("item", new ItemArgument(commandRegistryAccess, true)).executes((ctx) -> {
+ return GiveCommand.giveItem(ctx.getSource(), ItemArgument.getItem(ctx, "item"), EntityArgument.getPlayers(ctx, "targets"), 1);
+ })
+ .then(net.minecraft.commands.Commands.argument("count", IntegerArgumentType.integer(1)).executes((ctx) -> {
+ return GiveCommand.giveItem(ctx.getSource(), ItemArgument.getItem(ctx, "item"), EntityArgument.getPlayers(ctx, "targets"), IntegerArgumentType.getInteger(ctx, "count"));
+ }))
+ )
+ ).build();
+ setClientNodes(node);
+ dispatcher.getRoot().addChild(node);
+ }
+ static void setClientNodes(com.mojang.brigadier.tree.CommandNode<net.minecraft.commands.CommandSourceStack> node) {
+ if (node instanceof com.mojang.brigadier.tree.ArgumentCommandNode<net.minecraft.commands.CommandSourceStack,?> argumentNode) {
+ if (argumentNode.getType() instanceof ItemArgument) {
+ node.clientNode = new com.mojang.brigadier.tree.ArgumentCommandNode<>(
+ argumentNode.getName(),
+ com.mojang.brigadier.arguments.StringArgumentType.greedyString(),
+ argumentNode.getCommand(),
+ argumentNode.getRequirement(),
+ argumentNode.getRedirect(),
+ argumentNode.getRedirectModifier(),
+ argumentNode.isFork(),
+ (ctx, builder) -> builder.buildFuture()
+ );
+ }
+ }
+ node.getChildren().forEach(GiveCommand::setClientNodes);
+ // Paper end - support component removals with a custom pgive command
}
private static int giveItem(CommandSourceStack source, ItemInput item, Collection<ServerPlayer> targets, int count) throws CommandSyntaxException {
diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
@@ -0,0 +0,0 @@ public final class VanillaCommandWrapper extends BukkitCommand {
vanillaCommand = vanillaCommand.getRedirect();
}
final String commandName = vanillaCommand.getName();
+ if ("pgive".equals(stripDefaultNamespace(commandName))) {
+ return "bukkit.command.paper.pgive";
+ }
return "minecraft.command." + stripDefaultNamespace(commandName);
}
diff --git a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
+++ b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
@@ -0,0 +0,0 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase {
Set<String> foundPerms = new HashSet<>();
for (CommandNode<CommandSourceStack> child : root.getChildren()) {
final String vanillaPerm = VanillaCommandWrapper.getPermission(child);
+ if ("bukkit.command.paper.pgive".equals(vanillaPerm)) { // skip our custom give command
+ continue;
+ }
if (!perms.contains(vanillaPerm)) {
missing.add("Missing permission for " + child.getName() + " (" + vanillaPerm + ") command");
} else {