mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-30 16:19:03 +01:00
988
This commit is contained in:
parent
8a6e31ec59
commit
7289589315
32 changed files with 19 additions and 272 deletions
|
@ -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
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 {
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
|
@ -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 {
|
|
Loading…
Reference in a new issue