From 4853a65e7c5159eeade483f8b5403e951e10ce19 Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 28 Jun 2024 21:46:30 +0200 Subject: [PATCH] feat: implement graceful world bounds check where appropriate (#2804) - closes #2494 --- .../exception/OutsideWorldBoundsException.java | 17 +++++++++++++++++ .../java/com/sk89q/worldedit/WorldEdit.java | 16 ++++++++++++++++ .../worldedit/command/UtilityCommands.java | 14 +++++++++++--- .../exception/WorldEditExceptionConverter.java | 6 ++++++ .../src/main/resources/lang/strings.json | 1 + 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/OutsideWorldBoundsException.java diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/OutsideWorldBoundsException.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/OutsideWorldBoundsException.java new file mode 100644 index 0000000000..73d871135b --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/OutsideWorldBoundsException.java @@ -0,0 +1,17 @@ +package com.fastasyncworldedit.core.exception; + +import com.sk89q.worldedit.WorldEditException; + +public class OutsideWorldBoundsException extends WorldEditException { + + private final int y; + + public OutsideWorldBoundsException(int y) { + this.y = y; + } + + public int y() { + return y; + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java index be4c9af8c5..402310def2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -21,6 +21,7 @@ import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; +import com.fastasyncworldedit.core.exception.OutsideWorldBoundsException; import com.fastasyncworldedit.core.exception.RadiusLimitException; import com.fastasyncworldedit.core.extension.factory.TransformFactory; import com.fastasyncworldedit.core.extent.ResettableExtent; @@ -46,6 +47,7 @@ import com.sk89q.worldedit.extension.platform.Locatable; import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.PlatformManager; +import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.pattern.Pattern; @@ -523,6 +525,20 @@ public void checkMaxBrushRadius(Expression expression, Actor actor) { throw new BrushRadiusLimitException(max); } } + + /** + * Check if the given position is contained by the extent's min/max height + * + * @param position Position to check + * @param extent Extent to check in + * @throws OutsideWorldBoundsException If the position is outside the world height limits + * @since TODO + */ + public void checkExtentHeightBounds(BlockVector3 position, Extent extent) { + if (position.y() < extent.getMinY() || position.y() > extent.getMaxY()) { + throw new OutsideWorldBoundsException(position.y()); + } + } //FAWE end /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index a289f7cff0..c81db21d83 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -242,6 +242,7 @@ public int fill( we.checkMaxRadius(depth, actor); BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); int affected = editSession.fillDirection(pos, pattern, radius, depth, direction); actor.print(Caption.of("worldedit.fill.created", TextComponent.of(affected))); return affected; @@ -330,6 +331,7 @@ public int fillr( we.checkMaxRadius(radius, actor); BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); int affected = editSession.fillXZ(pos, pattern, radius, depth, true); actor.print(Caption.of("worldedit.fillr.created", TextComponent.of(affected))); return affected; @@ -357,7 +359,9 @@ public int drain( double radius = radiusExp.evaluate(); radius = Math.max(0, radius); we.checkMaxRadius(radius, actor); - int affected = editSession.drainArea(session.getPlacementPosition(actor), radius, waterlogged, plants); + BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); + int affected = editSession.drainArea(pos, radius, waterlogged, plants); actor.print(Caption.of("worldedit.drain.drained", TextComponent.of(affected))); return affected; } @@ -376,7 +380,9 @@ public int fixLava( ) throws WorldEditException { radius = Math.max(0, radius); we.checkMaxRadius(radius, actor); - int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.LAVA); + BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); + int affected = editSession.fixLiquid(pos, radius, BlockTypes.LAVA); actor.print(Caption.of("worldedit.fixlava.fixed", TextComponent.of(affected))); return affected; } @@ -395,7 +401,9 @@ public int fixWater( ) throws WorldEditException { radius = Math.max(0, radius); we.checkMaxRadius(radius, actor); - int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.WATER); + BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); + int affected = editSession.fixLiquid(pos, radius, BlockTypes.WATER); actor.print(Caption.of("worldedit.fixwater.fixed", TextComponent.of(affected))); return affected; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java index b07f3f61d4..b3b3b5df8f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java @@ -21,6 +21,7 @@ import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; +import com.fastasyncworldedit.core.exception.OutsideWorldBoundsException; import com.fastasyncworldedit.core.exception.RadiusLimitException; import com.fastasyncworldedit.core.internal.exception.FaweException; import com.google.common.collect.ImmutableList; @@ -146,6 +147,11 @@ public void convert(BrushRadiusLimitException e) throws CommandException { public void convert(RadiusLimitException e) throws CommandException { throw newCommandException(Caption.of("fawe.error.limit.max-radius", TextComponent.of(e.getMaxRadius())), e); } + + @ExceptionMatch + public void convert(OutsideWorldBoundsException e) throws CommandException { + throw newCommandException(Caption.of("fawe.cancel.reason.world.limit", TextComponent.of(e.y())), e); + } //FAWE end @ExceptionMatch diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index a8dddbdcfa..16e10a00d3 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -164,6 +164,7 @@ "fawe.cancel.reason.no.region.not.added": "Not added to region", "fawe.cancel.reason.player-only": "This operation requires a player, and cannot be executed from console, or without an actor.", "fawe.cancel.reason.actor-required": "This operation requires an actor.", + "fawe.cancel.reason.world.limit": "This operation cannot be performed at y={0} as it is outside world limits.", "fawe.cancel.worldedit.failed.load.chunk": "Skipped loading chunk: {0};{1}. Try increasing chunk-wait.", "fawe.navigation.no.block": "No block in sight! (or too far)", "fawe.selection.sel.max": "{0} points maximum.",