fill command event

This commit is contained in:
Yannick Lamprecht 2024-01-13 22:04:47 +01:00
parent 5e73c555bc
commit eec6c43fab
2 changed files with 293 additions and 0 deletions

View File

@ -0,0 +1,240 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yannick Lamprecht <yannicklamprecht@live.de>
Date: Sat, 13 Jan 2024 20:46:18 +0100
Subject: [PATCH] fill command event
diff --git a/src/main/java/io/papermc/paper/event/command/FillCommandEvent.java b/src/main/java/io/papermc/paper/event/command/FillCommandEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e6c4a8809e052a7e68e3ffc3b33eeb07d111f6a
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/command/FillCommandEvent.java
@@ -0,0 +1,95 @@
+package io.papermc.paper.event.command;
+
+import org.bukkit.block.BlockState;
+import org.bukkit.command.CommandSender;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.util.BoundingBox;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Triggers when fill command is executed
+ * For reference <a href="https://minecraft.wiki/w/Commands/fill">Minecraft Wiki Fill Command</a>
+ */
+public class FillCommandEvent extends Event implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+
+ private final CommandSender commandSender;
+ private final BoundingBox boundingBox;
+ private final BlockState state;
+ private final FillMode fillMode;
+ private boolean cancel = false;
+
+
+ /**
+ * Ctor
+ *
+ * @param commandSender the sender who executed the command
+ * @param fillMode the fill mode {@link FillMode}
+ */
+ public FillCommandEvent(@NotNull CommandSender commandSender, @NotNull BoundingBox boundingBox, @NotNull BlockState state, @NotNull FillMode fillMode) {
+ this.commandSender = commandSender;
+ this.boundingBox = boundingBox;
+ this.state = state;
+ this.fillMode = fillMode;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public @NotNull HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ /***
+ * Returns the sender of the command.
+ * @return the command sender
+ */
+ public @NotNull CommandSender getCommandSender() {
+ return commandSender;
+ }
+
+
+ /**
+ * Returns the fill mode.
+ * It is one of destroy|hollow|keep|outline|replace
+ *
+ *
+ * @return the fill mode
+ */
+ public @NotNull FillMode getFillMode() {
+ return fillMode;
+ }
+
+ /**
+ * Specifies the bounding box of the two opposing corner blocks of the region to be filled (the "fill region").
+ *
+ * @return the selection bounding box
+ */
+ public @NotNull BoundingBox getBoundingBox() {
+ return boundingBox.clone();
+ }
+
+ /**
+ * Is the state that will be set by the fill command
+ *
+ * @return the block state that will be set
+ */
+ public @NotNull BlockState getState() {
+ return state;
+ }
+
+
+ @Override
+ public boolean isCancelled() {
+ return cancel;
+ }
+
+ @Override
+ public void setCancelled(final boolean cancel) {
+ this.cancel = cancel;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/command/FillMode.java b/src/main/java/io/papermc/paper/event/command/FillMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..20afd62e25b39e416e851ef436cc8429595145ca
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/command/FillMode.java
@@ -0,0 +1,127 @@
+package io.papermc.paper.event.command;
+
+import java.util.function.Predicate;
+import org.bukkit.Location;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * The placement mode of the fill command see minecraft wiki
+ * <a href="https://minecraft.wiki/w/Commands/fill">FillCommand</a>
+ */
+public sealed interface FillMode {
+
+ /**
+ * Replaces all blocks (including air) in the fill region with the specified block,
+ * without dropping blocks or block contents as entities.
+ * Optionally, instead of specifying a data tag for the replacing block,
+ * block ID and data values may be specified to limit which blocks are replaced.
+ */
+ static @NotNull FillMode replace(@Nullable Predicate<Location> filter) {
+ return new Replace(filter);
+ }
+
+ /**
+ * Replaces all blocks (including air) in the fill region with the specified block,
+ * dropping the existing blocks (including those that are unchanged)
+ * and block contents as entities as if they had been mined with an unenchanted diamond shovel or pickaxe.
+ * (Blocks that can be mined only with shears, such as vines, do not drop; neither do liquids.)
+ */
+ static @NotNull FillMode destroy() {
+ return new Destroy();
+ }
+
+ /**
+ * Replaces only the air blocks in the fill region with the specified block.
+ */
+ static @NotNull FillMode keep() {
+ return new Keep();
+ }
+
+ /**
+ * Replaces only the blocks on the outer edge of the fill region with the specified block.
+ * Inner blocks are changed to air, dropping their contents as entities but not themselves.
+ * If the fill region has no inner blocks (because it is smaller than three blocks in at least one dimension),
+ * acts like replace.
+ */
+ static @NotNull FillMode hollow() {
+ return new Hollow();
+ }
+
+ /**
+ * Replaces only the blocks on the outer edge of the fill region with the specified block.
+ * Inner blocks are not affected.
+ * If the fill region has no inner blocks (because it is smaller than three blocks in at least one dimension),
+ * acts like replace.
+ */
+ static @NotNull FillMode outline() {
+ return new Outline();
+ }
+
+
+ /**
+ * Replaces all blocks (including air) in the fill region with the specified block,
+ * without dropping blocks or block contents as entities.
+ * Optionally, instead of specifying a data tag for the replacing block,
+ * block ID and data values may be specified to limit which blocks are replaced.
+ */
+ final class Replace implements FillMode {
+ private final @Nullable Predicate<Location> filter;
+
+ Replace(@Nullable Predicate<Location> filter) {
+ this.filter = filter;
+ }
+
+ public @Nullable Predicate<Location> filter() {
+ return filter;
+ }
+ }
+
+ /**
+ * Replaces all blocks (including air) in the fill region with the specified block,
+ * dropping the existing blocks (including those that are unchanged)
+ * and block contents as entities as if they had been mined with an unenchanted diamond shovel or pickaxe.
+ * (Blocks that can be mined only with shears, such as vines, do not drop; neither do liquids.)
+ */
+ final class Destroy implements FillMode {
+ /**
+ *
+ */
+ Destroy() {
+ }
+
+ }
+
+ /**
+ * Replaces only the air blocks in the fill region with the specified block.
+ */
+ static final class Keep implements FillMode {
+ /**
+ *
+ */
+ Keep() {
+ }
+ }
+
+ /**
+ * Replaces only the blocks on the outer edge of the fill region with the specified block.
+ * Inner blocks are changed to air, dropping their contents as entities but not themselves.
+ * If the fill region has no inner blocks (because it is smaller than three blocks in at least one dimension),
+ * acts like replace.
+ */
+ static final class Hollow implements FillMode {
+ Hollow() {
+ }
+ }
+
+ /**
+ * Replaces only the blocks on the outer edge of the fill region with the specified block.
+ * Inner blocks are not affected.
+ * If the fill region has no inner blocks (because it is smaller than three blocks in at least one dimension),
+ * acts like replace.
+ */
+ static final class Outline implements FillMode {
+ Outline() {
+ }
+ }
+}

View File

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yannick Lamprecht <yannicklamprecht@live.de>
Date: Sat, 13 Jan 2024 22:00:48 +0100
Subject: [PATCH] fill command event
== AT ==
public net.minecraft.commands.arguments.blocks.BlockInput tag
diff --git a/src/main/java/net/minecraft/server/commands/FillCommand.java b/src/main/java/net/minecraft/server/commands/FillCommand.java
index 287e0b193060829174d9ac7d127c3034c5eee1e1..1fdb27f64e9d4da5852a6723005f0626453480de 100644
--- a/src/main/java/net/minecraft/server/commands/FillCommand.java
+++ b/src/main/java/net/minecraft/server/commands/FillCommand.java
@@ -67,6 +67,14 @@ public class FillCommand {
ServerLevel serverLevel = source.getLevel();
int k = 0;
+ // Paper start - add fill command event
+ boolean cancelled = new io.papermc.paper.event.command.FillCommandEvent(
+ source.getBukkitSender(),
+ new org.bukkit.util.BoundingBox(range.minX(), range.minY(), range.minZ(), range.maxX(), range.maxY(), range.maxZ()),
+ org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(block.getState(), block.tag),
+ fromNMS(mode, filter)
+ ).callEvent();
+ if(!cancelled) { // Paper end - add fill command event
for(BlockPos blockPos : BlockPos.betweenClosed(range.minX(), range.minY(), range.minZ(), range.maxX(), range.maxY(), range.maxZ())) {
if (filter == null || filter.test(new BlockInWorld(serverLevel, blockPos, true))) {
BlockInput blockInput = mode.filter.filter(range, blockPos, block, serverLevel);
@@ -85,6 +93,7 @@ public class FillCommand {
Block block2 = serverLevel.getBlockState(blockPos2).getBlock();
serverLevel.blockUpdated(blockPos2, block2);
}
+ } // Paper - add fill command event
if (k == 0) {
throw ERROR_FAILED.create();
@@ -97,6 +106,17 @@ public class FillCommand {
}
}
}
+ // Paper start - add fill command event
+ private static io.papermc.paper.event.command.FillMode fromNMS(Mode mode, @org.jetbrains.annotations.Nullable Predicate<BlockInWorld> filter) {
+ return switch (mode) {
+ case REPLACE -> io.papermc.paper.event.command.FillMode.replace(
+ filter == null ? null : (org.bukkit.Location location) -> filter.test(new BlockInWorld(((org.bukkit.craftbukkit.CraftWorld)location.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toBlockPosition(location), true))
+ );
+ case OUTLINE -> io.papermc.paper.event.command.FillMode.outline();
+ case HOLLOW -> io.papermc.paper.event.command.FillMode.hollow();
+ case DESTROY -> io.papermc.paper.event.command.FillMode.destroy();
+ };
+ } // Paper end - add fill command event
static enum Mode {
REPLACE((range, pos, block, world) -> {