diff --git a/patches/server/Add-UnknownCommandEvent.patch b/patches/server/Add-UnknownCommandEvent.patch index c96475e02f..b798f26e42 100644 --- a/patches/server/Add-UnknownCommandEvent.patch +++ b/patches/server/Add-UnknownCommandEvent.patch @@ -28,22 +28,6 @@ diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -0,0 +0,0 @@ public class Commands { - public static final int LEVEL_ADMINS = 3; - public static final int LEVEL_OWNERS = 4; - private final com.mojang.brigadier.CommandDispatcher dispatcher = new com.mojang.brigadier.CommandDispatcher(); -+ public final java.util.List> vanillaCommandNodes = new java.util.ArrayList<>(); // Paper - Add UnknownCommandEvent - - public Commands(Commands.CommandSelection environment, CommandBuildContext commandRegistryAccess) { - this(); // CraftBukkit -@@ -0,0 +0,0 @@ public class Commands { - if (environment.includeIntegrated) { - PublishCommand.register(this.dispatcher); - } -+ this.vanillaCommandNodes.addAll(this.dispatcher.getRoot().getChildren()); // Paper - Add UnknownCommandEvent - - // CraftBukkit start - } @@ -0,0 +0,0 @@ public class Commands { commandlistenerwrapper.getServer().getProfiler().push(() -> { return "/" + s; @@ -68,14 +52,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - commandlistenerwrapper.sendFailure(ComponentUtils.fromMessage(commandsyntaxexception.getRawMessage())); + // Paper start - Add UnknownCommandEvent + final net.kyori.adventure.text.TextComponent.Builder builder = net.kyori.adventure.text.Component.text(); -+ if ((parseresults.getContext().getNodes().isEmpty() || !this.vanillaCommandNodes.contains(parseresults.getContext().getNodes().get(0).getNode()))) { -+ if (!org.spigotmc.SpigotConfig.unknownCommandMessage.isEmpty()) { -+ builder.append(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.unknownCommandMessage)); -+ } -+ } else { -+ // commandlistenerwrapper.sendFailure(ComponentUtils.fromMessage(commandsyntaxexception.getRawMessage())); -+ builder.color(net.kyori.adventure.text.format.NamedTextColor.RED).append(io.papermc.paper.brigadier.PaperBrigadier.componentFromMessage(commandsyntaxexception.getRawMessage())); -+ // Paper end - Add UnknownCommandEvent ++ // commandlistenerwrapper.sendFailure(ComponentUtils.fromMessage(commandsyntaxexception.getRawMessage())); ++ builder.color(net.kyori.adventure.text.format.NamedTextColor.RED).append(io.papermc.paper.brigadier.PaperBrigadier.componentFromMessage(commandsyntaxexception.getRawMessage())); ++ // Paper end - Add UnknownCommandEvent if (commandsyntaxexception.getInput() != null && commandsyntaxexception.getCursor() >= 0) { int i = Math.min(commandsyntaxexception.getInput().length(), commandsyntaxexception.getCursor()); MutableComponent ichatmutablecomponent = Component.empty().withStyle(ChatFormatting.GRAY).withStyle((chatmodifier) -> { @@ -90,7 +69,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .append(net.kyori.adventure.text.Component.newline()) + .append(io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); + } -+ } + org.bukkit.event.command.UnknownCommandEvent event = new org.bukkit.event.command.UnknownCommandEvent(commandlistenerwrapper.getBukkitSender(), s, org.spigotmc.SpigotConfig.unknownCommandMessage.isEmpty() ? null : builder.build()); + org.bukkit.Bukkit.getServer().getPluginManager().callEvent(event); + if (event.message() != null) { @@ -103,14 +81,6 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/ja index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -0,0 +0,0 @@ public final class CraftServer implements Server { - } - node = clone; - } -+ dispatcher.vanillaCommandNodes.add(node); // Paper - - dispatcher.getDispatcher().getRoot().addChild(node); - } else { @@ -0,0 +0,0 @@ public final class CraftServer implements Server { // Spigot start diff --git a/patches/server/Add-experimental-improved-give-command.patch b/patches/server/Add-experimental-improved-give-command.patch new file mode 100644 index 0000000000..f50207ee8c --- /dev/null +++ b/patches/server/Add-experimental-improved-give-command.patch @@ -0,0 +1,218 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +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 { + 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) { +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; + private final DataComponentMap components; ++ @javax.annotation.Nullable private final net.minecraft.core.component.DataComponentPatch patch; // Paper + + public ItemInput(Holder item, DataComponentMap components) { ++ // Paper start ++ this(item, components, null); ++ } ++ public ItemInput(Holder 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> SUGGEST_NOTHING = SuggestionsBuilder::buildFuture; + final HolderLookup.RegistryLookup items; + final DynamicOps 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> 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) { +@@ -0,0 +0,0 @@ public class ItemParser { + @Override + public void visitComponent(DataComponentType type, T value) { + builder.set(type, value); ++ // Paper start - support component removals ++ patchBuilder.set(type, value); ++ } ++ @Override ++ public void visitComponentRemove(final DataComponentType type) { ++ patchBuilder.remove(type); ++ // Paper end - support component removals + } + }); + Holder 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, DataComponentMap components) throws CommandSyntaxException { +@@ -0,0 +0,0 @@ public class ItemParser { + return suggestionsVisitor.resolveSuggestions(builder, stringReader); + } + +- public static record ItemResult(Holder item, DataComponentMap components) { ++ public static record ItemResult(Holder 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 suggestComponentAssignment(SuggestionsBuilder builder) { ++ // Paper start - support component removals ++ return this.suggestComponentAssignment(builder, true); ++ } ++ private CompletableFuture suggestComponentAssignment(SuggestionsBuilder builder, boolean suggestRemove) { ++ if (suggestRemove) builder.suggest("!", Component.literal("Remove a data component")); ++ // Paper end - support component removals + String string = builder.getRemaining().toLowerCase(Locale.ROOT); + 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 void visitComponent(DataComponentType type, T value) { + } ++ default void visitComponentRemove(DataComponentType type) {} // Paper + + default void visitSuggestions(Function> 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 node = net.minecraft.commands.Commands ++ .literal("pgive").requires((commandlistenerwrapper) -> commandlistenerwrapper.hasPermission(2)) ++ .then(net.minecraft.commands.Commands.argument("targets", EntityArgument.players()) ++ .then(net.minecraft.commands.Commands.argument("item", new ItemArgument(commandRegistryAccess, true)).executes((commandcontext) -> { ++ return GiveCommand.giveItem((CommandSourceStack) commandcontext.getSource(), ItemArgument.getItem(commandcontext, "item"), EntityArgument.getPlayers(commandcontext, "targets"), 1); ++ }) ++ .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")); ++ })) ++ ) ++ ).build(); ++ setClientNodes(node); ++ dispatcher.getRoot().addChild(node); ++ } ++ static void setClientNodes(com.mojang.brigadier.tree.CommandNode node) { ++ if (node instanceof com.mojang.brigadier.tree.ArgumentCommandNode 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 targets, int count) throws CommandSyntaxException { diff --git a/patches/server/Brigadier-Mojang-API.patch b/patches/server/Brigadier-Mojang-API.patch index 066ae5f6de..f376b230ac 100644 --- a/patches/server/Brigadier-Mojang-API.patch +++ b/patches/server/Brigadier-Mojang-API.patch @@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private final RedirectModifier modifier; private final boolean forks; private Command command; -+ public LiteralCommandNode clientNode; // Paper - Brigadier API ++ public CommandNode clientNode; // Paper - Brigadier API // CraftBukkit start public void removeCommand(String name) { this.children.remove(name); diff --git a/patches/server/Don-t-lose-removed-data-components-in-ItemMeta.patch b/patches/server/Don-t-lose-removed-data-components-in-ItemMeta.patch new file mode 100644 index 0000000000..9811f0d424 --- /dev/null +++ b/patches/server/Don-t-lose-removed-data-components-in-ItemMeta.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Fri, 26 Apr 2024 21:33:20 -0700 +Subject: [PATCH] Don't lose removed data components in ItemMeta + + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + return this; + } + ++ // Paper start - support removing component types ++ Applicator remove(DataComponentType type) { ++ this.builder.remove(type); ++ return this; ++ } ++ // Paper end - support removing component types ++ + DataComponentPatch build() { + return this.builder.build(); + } +@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + + Set, Optional>> keys = tag.entrySet(); + for (Map.Entry, Optional> key : keys) { +- if (!CraftMetaItem.getHandledTags().contains(key.getKey())) { ++ if (key.getValue().isEmpty()) { ++ this.unhandledTags.remove(key.getKey()); ++ } else if (!CraftMetaItem.getHandledTags().contains(key.getKey())) { + key.getValue().ifPresentOrElse((value) -> { + this.unhandledTags.set((DataComponentType) key.getKey(), value); + }, () -> { +@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + } + + for (Map.Entry, Optional> e : this.unhandledTags.build().entrySet()) { +- e.getValue().ifPresent((value) -> { ++ e.getValue().ifPresentOrElse((value) -> { + itemTag.builder.set((DataComponentType) e.getKey(), value); +- }); ++ }, () -> itemTag.remove(e.getKey())); + } + + if (!this.persistentDataContainer.isEmpty()) { diff --git a/patches/server/MC-Dev-fixes.patch b/patches/server/MC-Dev-fixes.patch index 392f7a2c14..85b9daf2b6 100644 --- a/patches/server/MC-Dev-fixes.patch +++ b/patches/server/MC-Dev-fixes.patch @@ -4,6 +4,18 @@ Date: Wed, 30 Mar 2016 19:36:20 -0400 Subject: [PATCH] MC Dev fixes +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 String getItemName() { +- return this.item.unwrapKey().map(ResourceKey::location).orElseGet(() -> "unknown[" + this.item + "]").toString(); ++ return this.item.unwrapKey().map(ResourceKey::location).orElseGet(() -> "unknown[" + this.item + "]").toString(); // Paper - decompile fix + } + } diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/core/BlockPos.java diff --git a/patches/server/More-Enchantment-API.patch b/patches/server/More-Enchantment-API.patch index 1475ed4189..5813bba79d 100644 --- a/patches/server/More-Enchantment-API.patch +++ b/patches/server/More-Enchantment-API.patch @@ -22,28 +22,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override @@ -0,0 +0,0 @@ public class CraftEnchantment extends Enchantment implements Handleable getActiveSlots() { -+ return java.util.stream.Stream.of(handle.definition.slots()).map(org.bukkit.craftbukkit.CraftEquipmentSlot::getSlot).collect(java.util.stream.Collectors.toSet()); ++ return java.util.stream.Stream.of(this.handle.definition.slots()).map(org.bukkit.craftbukkit.CraftEquipmentSlot::getSlot).collect(java.util.stream.Collectors.toSet()); + } // Paper end diff --git a/patches/server/PortalCreateEvent-needs-to-know-its-entity.patch b/patches/server/PortalCreateEvent-needs-to-know-its-entity.patch index deae9712cf..33d46f37ad 100644 --- a/patches/server/PortalCreateEvent-needs-to-know-its-entity.patch +++ b/patches/server/PortalCreateEvent-needs-to-know-its-entity.patch @@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify, net.minecraft.world.item.context.UseOnContext context) { ++ protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify, @javax.annotation.Nullable net.minecraft.world.item.context.UseOnContext context) { + // Paper end - UseOnContext param if (!oldState.is(state.getBlock())) { if (BaseFireBlock.inPortalDimension(world)) { @@ -103,7 +103,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return this.createPortalBlocks(null); + } + -+ public boolean createPortalBlocks(net.minecraft.world.item.context.UseOnContext useOnContext) { ++ public boolean createPortalBlocks(@Nullable net.minecraft.world.item.context.UseOnContext useOnContext) { + // Paper end - UseOnContext param org.bukkit.World bworld = this.level.getMinecraftWorld().getWorld(); diff --git a/patches/server/Properly-handle-pdc-and-custom-tags-in-ItemMeta.patch b/patches/server/Properly-handle-pdc-and-custom-tags-in-ItemMeta.patch index 4d94c3ce12..7234750649 100644 --- a/patches/server/Properly-handle-pdc-and-custom-tags-in-ItemMeta.patch +++ b/patches/server/Properly-handle-pdc-and-custom-tags-in-ItemMeta.patch @@ -30,8 +30,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.customTag != null) { itemTag.put(CraftMetaItem.CUSTOM_DATA, CustomData.of(this.customTag)); -+ this.customTag.remove(CraftMetaItem.BUKKIT_CUSTOM_TAG.BUKKIT); -+ if (this.customTag.isEmpty()) this.customTag = null; ++ this.customTag.remove(CraftMetaItem.BUKKIT_CUSTOM_TAG.BUKKIT); // Paper - remove PDC from custom tag ++ if (this.customTag.isEmpty()) this.customTag = null; // Paper - reset custom tag if empty } } diff --git a/patches/server/Vanilla-command-permission-fixes.patch b/patches/server/Vanilla-command-permission-fixes.patch index c152b0c69c..22f70bacfe 100644 --- a/patches/server/Vanilla-command-permission-fixes.patch +++ b/patches/server/Vanilla-command-permission-fixes.patch @@ -37,8 +37,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -0,0 +0,0 @@ public class Commands { + PublishCommand.register(this.dispatcher); } - this.vanillaCommandNodes.addAll(this.dispatcher.getRoot().getChildren()); // Paper - Add UnknownCommandEvent + // Paper start - Vanilla command permission fixes + for (final CommandNode node : this.dispatcher.getRoot().getChildren()) {