From 2b317fcfd228a8f50930b8b244d13be5231c75f6 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sat, 26 Jul 2025 10:56:28 +0100 Subject: [PATCH] feat: apply coord limits to more commands - fixes #4375 --- .../plotsquared/core/command/MainCommand.java | 2 +- .../java/com/plotsquared/core/plot/Plot.java | 71 ++++++++++++++++++- Core/src/main/resources/lang/messages_en.json | 1 + 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/MainCommand.java b/Core/src/main/java/com/plotsquared/core/command/MainCommand.java index 1cdf06878..507883a13 100644 --- a/Core/src/main/java/com/plotsquared/core/command/MainCommand.java +++ b/Core/src/main/java/com/plotsquared/core/command/MainCommand.java @@ -275,7 +275,7 @@ public class MainCommand extends Command { private CompletableFuture> prepareArguments(CommandExecutionData data) { if (data.args().length >= 2) { PlotArea area = data.player().getApplicablePlotArea(); - Plot newPlot = Plot.fromString(area, data.args()[0]); + Plot newPlot = Plot.fromString(area, data.args()[0], data.player()); return preparePlotArgument(newPlot, data, area) .thenApply(d -> d.flatMap(x -> prepareFlagArgument(x, area))); } else { diff --git a/Core/src/main/java/com/plotsquared/core/plot/Plot.java b/Core/src/main/java/com/plotsquared/core/plot/Plot.java index 0d28fc41e..e580b14f9 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java +++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java @@ -321,7 +321,8 @@ public class Plot { } /** - * Get the plot from a string. + * Get the plot from a string. Performs a check to ensure Plot#getBottomAbs is not outside world bounds + * (x/z +/- 30,000,000) to prevent crashes * * @param player Provides a context for what world to search in. Prefixing the term with 'world_name;' will override this context. * @param arg The search term @@ -332,6 +333,31 @@ public class Plot { final @Nullable PlotPlayer player, final @Nullable String arg, final boolean message + ) { + Plot plot = getPlotFromStringUnchecked(player, arg, message); + if (plot != null && !WorldUtil.isValidLocation(plot.getBottomAbs())) { + if (message) { + (player == null ? ConsolePlayer.getConsole() : player).sendMessage(TranslatableCaption.of( + "invalid.world_location_plot")); + } + return null; + } + return plot; + } + + /** + * Get the plot from a string. Does not perform a check on world bounds. + * + * @param player Provides a context for what world to search in. Prefixing the term with 'world_name;' will override this context. + * @param arg The search term + * @param message If a message should be sent to the player if a plot cannot be found + * @return The plot if only 1 result is found, or null + * @since TODO + */ + public static @Nullable Plot getPlotFromStringUnchecked( + final @Nullable PlotPlayer player, + final @Nullable String arg, + final boolean message ) { if (arg == null) { if (player == null) { @@ -389,13 +415,51 @@ public class Plot { } /** - * Gets a plot from a string e.g. [area];[id] + * Gets a plot from a string e.g. [area];[id]. Performs a check to ensure Plot#getBottomAbs is not outside world bounds + * (x/z +/- 30,000,000) to prevent crashes * * @param defaultArea if no area is specified * @param string plot id/area + id * @return New or existing plot object */ public static @Nullable Plot fromString(final @Nullable PlotArea defaultArea, final @NonNull String string) { + return fromString(defaultArea, string, null); + } + + /** + * Gets a plot from a string e.g. [area];[id]. Performs a check to ensure Plot#getBottomAbs is not outside world bounds + * (x/z +/- 30,000,000) to prevent crashes + * + * @param defaultArea if no area is specified + * @param string plot id/area + id + * @param player {@link PlotPlayer} player to notify if plot is invalid (outside bounds) + * @return New or existing plot object + * @since TODO + */ + public static @Nullable Plot fromString( + final @Nullable PlotArea defaultArea, + final @NonNull String string, + final @Nullable PlotPlayer player + ) { + Plot plot = fromStringUnchecked(defaultArea, string); + if (plot != null && !WorldUtil.isValidLocation(plot.getBottomAbs())) { + if (player != null) { + player.sendMessage(TranslatableCaption.of("invalid.world_location_plot")); + } + return null; + } + return plot; + } + + /** + * Gets a plot from a string e.g. [area];[id]. Does not perform a check on world bounds. + * + * @param defaultArea if no area is specified + * @param string plot id/area + id + * @return New or existing plot object + * @since TODO + */ + public static @Nullable Plot fromStringUnchecked(final @Nullable PlotArea defaultArea, final @NonNull String string) { final String[] split = string.split("[;,]"); if (split.length == 2) { if (defaultArea != null) { @@ -419,7 +483,8 @@ public class Plot { } /** - * Return a new/cached plot object at a given location. + * Return a new/cached plot object at a given location. Does not check world bounds for potential crashes, these should be + * performed before (or after) this method is used. * *

* Use {@link PlotPlayer#getCurrentPlot()} if a player is expected here. diff --git a/Core/src/main/resources/lang/messages_en.json b/Core/src/main/resources/lang/messages_en.json index 5e4dbb941..04c8825b5 100644 --- a/Core/src/main/resources/lang/messages_en.json +++ b/Core/src/main/resources/lang/messages_en.json @@ -234,6 +234,7 @@ "invalid.not_valid_number": "That's not a valid number within the range: ", "invalid.not_valid_plot_id": "That's not a valid plot ID.", "invalid.origin_cant_be_target": "The origin and target location cannot be the same.", + "invalid.world_location_plot": "The target plot is invalid.", "invalid.found_no_plots": "Found no plots with your search query.", "invalid.number_not_in_range": "That's not a valid number within the range: (, )", "invalid.number_not_positive": "That's not a positive number: ",