feat: implement graceful world bounds check where appropriate (#2804)

- closes #2494
This commit is contained in:
Jordan 2024-06-28 21:46:30 +02:00 committed by GitHub
parent 99a58f66cd
commit 4853a65e7c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 51 additions and 3 deletions

View File

@ -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;
}
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit;
import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; import com.fastasyncworldedit.core.exception.BrushRadiusLimitException;
import com.fastasyncworldedit.core.exception.OutsideWorldBoundsException;
import com.fastasyncworldedit.core.exception.RadiusLimitException; import com.fastasyncworldedit.core.exception.RadiusLimitException;
import com.fastasyncworldedit.core.extension.factory.TransformFactory; import com.fastasyncworldedit.core.extension.factory.TransformFactory;
import com.fastasyncworldedit.core.extent.ResettableExtent; import com.fastasyncworldedit.core.extent.ResettableExtent;
@ -46,6 +47,7 @@ import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Locatable; import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.PlatformManager; import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
@ -523,6 +525,20 @@ public final class WorldEdit {
throw new BrushRadiusLimitException(max); 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 //FAWE end
/** /**

View File

@ -242,6 +242,7 @@ public class UtilityCommands {
we.checkMaxRadius(depth, actor); we.checkMaxRadius(depth, actor);
BlockVector3 pos = session.getPlacementPosition(actor); BlockVector3 pos = session.getPlacementPosition(actor);
we.checkExtentHeightBounds(pos, editSession);
int affected = editSession.fillDirection(pos, pattern, radius, depth, direction); int affected = editSession.fillDirection(pos, pattern, radius, depth, direction);
actor.print(Caption.of("worldedit.fill.created", TextComponent.of(affected))); actor.print(Caption.of("worldedit.fill.created", TextComponent.of(affected)));
return affected; return affected;
@ -330,6 +331,7 @@ public class UtilityCommands {
we.checkMaxRadius(radius, actor); we.checkMaxRadius(radius, actor);
BlockVector3 pos = session.getPlacementPosition(actor); BlockVector3 pos = session.getPlacementPosition(actor);
we.checkExtentHeightBounds(pos, editSession);
int affected = editSession.fillXZ(pos, pattern, radius, depth, true); int affected = editSession.fillXZ(pos, pattern, radius, depth, true);
actor.print(Caption.of("worldedit.fillr.created", TextComponent.of(affected))); actor.print(Caption.of("worldedit.fillr.created", TextComponent.of(affected)));
return affected; return affected;
@ -357,7 +359,9 @@ public class UtilityCommands {
double radius = radiusExp.evaluate(); double radius = radiusExp.evaluate();
radius = Math.max(0, radius); radius = Math.max(0, radius);
we.checkMaxRadius(radius, actor); 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))); actor.print(Caption.of("worldedit.drain.drained", TextComponent.of(affected)));
return affected; return affected;
} }
@ -376,7 +380,9 @@ public class UtilityCommands {
) throws WorldEditException { ) throws WorldEditException {
radius = Math.max(0, radius); radius = Math.max(0, radius);
we.checkMaxRadius(radius, actor); 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))); actor.print(Caption.of("worldedit.fixlava.fixed", TextComponent.of(affected)));
return affected; return affected;
} }
@ -395,7 +401,9 @@ public class UtilityCommands {
) throws WorldEditException { ) throws WorldEditException {
radius = Math.max(0, radius); radius = Math.max(0, radius);
we.checkMaxRadius(radius, actor); 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))); actor.print(Caption.of("worldedit.fixwater.fixed", TextComponent.of(affected)));
return affected; return affected;
} }

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.internal.command.exception;
import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; import com.fastasyncworldedit.core.exception.BrushRadiusLimitException;
import com.fastasyncworldedit.core.exception.OutsideWorldBoundsException;
import com.fastasyncworldedit.core.exception.RadiusLimitException; import com.fastasyncworldedit.core.exception.RadiusLimitException;
import com.fastasyncworldedit.core.internal.exception.FaweException; import com.fastasyncworldedit.core.internal.exception.FaweException;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -146,6 +147,11 @@ public class WorldEditExceptionConverter extends ExceptionConverterHelper {
public void convert(RadiusLimitException e) throws CommandException { public void convert(RadiusLimitException e) throws CommandException {
throw newCommandException(Caption.of("fawe.error.limit.max-radius", TextComponent.of(e.getMaxRadius())), e); 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 //FAWE end
@ExceptionMatch @ExceptionMatch

View File

@ -164,6 +164,7 @@
"fawe.cancel.reason.no.region.not.added": "Not added to region", "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.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.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.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.navigation.no.block": "No block in sight! (or too far)",
"fawe.selection.sel.max": "{0} points maximum.", "fawe.selection.sel.max": "{0} points maximum.",