diff --git a/patches/minecraft/net/minecraft/commands/arguments/EntityArgument.java.patch b/patches/minecraft/net/minecraft/commands/arguments/EntityArgument.java.patch new file mode 100644 index 0000000000..b06e3596a1 --- /dev/null +++ b/patches/minecraft/net/minecraft/commands/arguments/EntityArgument.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/commands/arguments/EntityArgument.java ++++ b/net/minecraft/commands/arguments/EntityArgument.java +@@ -115,7 +_,7 @@ + if (s instanceof SharedSuggestionProvider sharedsuggestionprovider) { + StringReader stringreader = new StringReader(p_91483_.getInput()); + stringreader.setCursor(p_91483_.getStart()); +- EntitySelectorParser entityselectorparser = new EntitySelectorParser(stringreader, sharedsuggestionprovider.m_6761_(2)); ++ EntitySelectorParser entityselectorparser = new EntitySelectorParser(stringreader, net.minecraftforge.common.ForgeHooks.canUseEntitySelectors(sharedsuggestionprovider)); + + try { + entityselectorparser.m_121377_(); diff --git a/patches/minecraft/net/minecraft/commands/arguments/MessageArgument.java.patch b/patches/minecraft/net/minecraft/commands/arguments/MessageArgument.java.patch new file mode 100644 index 0000000000..c500e4a287 --- /dev/null +++ b/patches/minecraft/net/minecraft/commands/arguments/MessageArgument.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/commands/arguments/MessageArgument.java ++++ b/net/minecraft/commands/arguments/MessageArgument.java +@@ -134,7 +_,7 @@ + } + + Component m_232196_(CommandSourceStack p_232197_) throws CommandSyntaxException { +- return this.m_96849_(p_232197_, p_232197_.m_6761_(2)); ++ return this.m_96849_(p_232197_, net.minecraftforge.common.ForgeHooks.canUseEntitySelectors(p_232197_)); + } + + public Component m_96849_(CommandSourceStack p_96850_, boolean p_96851_) throws CommandSyntaxException { diff --git a/patches/minecraft/net/minecraft/commands/arguments/selector/EntitySelector.java.patch b/patches/minecraft/net/minecraft/commands/arguments/selector/EntitySelector.java.patch new file mode 100644 index 0000000000..60fb7cad0b --- /dev/null +++ b/patches/minecraft/net/minecraft/commands/arguments/selector/EntitySelector.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/commands/arguments/selector/EntitySelector.java ++++ b/net/minecraft/commands/arguments/selector/EntitySelector.java +@@ -87,7 +_,7 @@ + } + + private void m_121168_(CommandSourceStack p_121169_) throws CommandSyntaxException { +- if (this.f_121123_ && !p_121169_.m_6761_(2)) { ++ if (this.f_121123_ && !net.minecraftforge.common.ForgeHooks.canUseEntitySelectors(p_121169_)) { + throw EntityArgument.f_91441_.create(); + } + } diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index c7cb25cc3b..ef85dc72cc 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -32,6 +32,9 @@ import com.mojang.serialization.Lifecycle; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.ResourceLocationException; import net.minecraft.advancements.Advancement; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.core.*; import net.minecraft.network.chat.*; import net.minecraft.network.chat.contents.LiteralContents; @@ -147,6 +150,7 @@ import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.GameData; import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.registries.holdersets.ICustomHolderSet; +import net.minecraftforge.server.permission.PermissionAPI; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -1491,4 +1495,13 @@ public class ForgeHooks { return registryKey.getNamespace().equals("minecraft") ? registryKey.getPath() : registryKey.getNamespace() + "/" + registryKey.getPath(); } + + public static boolean canUseEntitySelectors(SharedSuggestionProvider provider) + { + if (provider instanceof CommandSourceStack source && source.getEntity() instanceof ServerPlayer player) + { + return PermissionAPI.getPermission(player, ForgeMod.USE_SELECTORS_PERMISSION); + } + return provider.hasPermission(Commands.LEVEL_GAMEMASTERS); + } } diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index 8d9e42d727..62a47fe340 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -14,6 +14,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; +import net.minecraft.commands.Commands; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.RangedAttribute; import net.minecraft.world.entity.item.ItemEntity; @@ -73,6 +74,9 @@ import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.network.filters.VanillaPacketSplitter; import net.minecraftforge.server.command.EnumArgument; import net.minecraftforge.server.command.ModIdArgument; +import net.minecraftforge.server.permission.events.PermissionGatherEvent; +import net.minecraftforge.server.permission.nodes.PermissionNode; +import net.minecraftforge.server.permission.nodes.PermissionTypes; import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.mcp.MCPVersion; @@ -461,6 +465,7 @@ public class ForgeMod MinecraftForge.EVENT_BUS.addListener(VillagerTradingManager::loadTrades); MinecraftForge.EVENT_BUS.register(MinecraftForge.INTERNAL_HANDLER); MinecraftForge.EVENT_BUS.addListener(this::mappingChanged); + MinecraftForge.EVENT_BUS.addListener(this::registerPermissionNodes); ForgeRegistries.ITEMS.tags().addOptionalTagDefaults(Tags.Items.ENCHANTING_FUELS, Set.of(ForgeRegistries.ITEMS.getDelegateOrThrow(Items.LAPIS_LAZULI))); } @@ -602,4 +607,12 @@ public class ForgeMod event.register(Registry.LOOT_ITEM_REGISTRY, new ResourceLocation("forge:loot_table_id"), () -> LootTableIdCondition.LOOT_TABLE_ID); event.register(Registry.LOOT_ITEM_REGISTRY, new ResourceLocation("forge:can_tool_perform_action"), () -> CanToolPerformAction.LOOT_CONDITION_TYPE); } + + public static final PermissionNode USE_SELECTORS_PERMISSION = new PermissionNode<>("forge", "use_entity_selectors", + PermissionTypes.BOOLEAN, (player, uuid, contexts) -> player != null && player.hasPermissions(Commands.LEVEL_GAMEMASTERS)); + + public void registerPermissionNodes(PermissionGatherEvent.Nodes event) + { + event.addNodes(USE_SELECTORS_PERMISSION); + } }