mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2025-07-03 22:24:43 +02:00
Compare commits
1 Commits
7.5.2
...
fix/IOOBE-
Author | SHA1 | Date | |
---|---|---|---|
9127e472b8 |
@ -593,7 +593,7 @@ public class PlayerEventListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Plot plot = area.getPlot(location);
|
Plot plot = area.getPlot(location);
|
||||||
if (plot != null && !plot.equals(lastPlot)) {
|
if (plot != null) {
|
||||||
final boolean result = DenyTeleportFlag.allowsTeleport(pp, plot);
|
final boolean result = DenyTeleportFlag.allowsTeleport(pp, plot);
|
||||||
// there is one possibility to still allow teleportation:
|
// there is one possibility to still allow teleportation:
|
||||||
// to is identical to the plot's home location, and untrusted-visit is true
|
// to is identical to the plot's home location, and untrusted-visit is true
|
||||||
|
@ -44,13 +44,8 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PlotSquared command class.
|
* PlotSquared command class.
|
||||||
*/
|
*/
|
||||||
@ -152,7 +147,8 @@ public class MainCommand extends Command {
|
|||||||
try {
|
try {
|
||||||
injector.getInstance(command);
|
injector.getInstance(command);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
LOGGER.error("Failed to register command {}", command.getCanonicalName(), e);
|
LOGGER.error("Failed to register command {}", command.getCanonicalName());
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,171 +236,111 @@ public class MainCommand extends Command {
|
|||||||
RunnableVal3<Command, Runnable, Runnable> confirm,
|
RunnableVal3<Command, Runnable, Runnable> confirm,
|
||||||
RunnableVal2<Command, CommandResult> whenDone
|
RunnableVal2<Command, CommandResult> whenDone
|
||||||
) {
|
) {
|
||||||
prepareArguments(new CommandExecutionData(player, args, confirm, whenDone, null))
|
// Optional command scope //
|
||||||
.thenCompose(executionData -> {
|
Location location = null;
|
||||||
if (executionData.isEmpty()) {
|
Plot plot = null;
|
||||||
return CompletableFuture.completedFuture(false);
|
boolean tp = false;
|
||||||
|
if (args.length >= 2) {
|
||||||
|
PlotArea area = player.getApplicablePlotArea();
|
||||||
|
Plot newPlot = Plot.fromString(area, args[0]);
|
||||||
|
if (newPlot != null && (player instanceof ConsolePlayer || newPlot.getArea()
|
||||||
|
.equals(area) || player.hasPermission(Permission.PERMISSION_ADMIN)
|
||||||
|
|| player.hasPermission(Permission.PERMISSION_ADMIN_AREA_SUDO))
|
||||||
|
&& !newPlot.isDenied(player.getUUID())) {
|
||||||
|
final Location newLoc;
|
||||||
|
if (newPlot.getArea() instanceof SinglePlotArea) {
|
||||||
|
newLoc = newPlot.isLoaded() ? newPlot.getCenterSynchronous() : Location.at("", 0, 0, 0);
|
||||||
|
} else {
|
||||||
|
newLoc = newPlot.getCenterSynchronous();
|
||||||
|
}
|
||||||
|
if (player.canTeleport(newLoc)) {
|
||||||
|
// Save meta
|
||||||
|
try (final MetaDataAccess<Location> locationMetaDataAccess
|
||||||
|
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
|
||||||
|
location = locationMetaDataAccess.get().orElse(null);
|
||||||
|
locationMetaDataAccess.set(newLoc);
|
||||||
}
|
}
|
||||||
var data = executionData.get();
|
try (final MetaDataAccess<Plot> plotMetaDataAccess
|
||||||
try {
|
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
|
||||||
return super.execute(data.player(), data.args(), data.confirm(), data.whenDone());
|
plot = plotMetaDataAccess.get().orElse(null);
|
||||||
} catch (CommandException e) {
|
plotMetaDataAccess.set(newPlot);
|
||||||
throw e;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LOGGER.error("A error occurred while executing plot command", e);
|
|
||||||
String message = e.getMessage();
|
|
||||||
if (message != null) {
|
|
||||||
data.player().sendMessage(
|
|
||||||
TranslatableCaption.of("errors.error"),
|
|
||||||
TagResolver.resolver("value", Tag.inserting(Component.text(message)))
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
data.player().sendMessage(
|
|
||||||
TranslatableCaption.of("errors.error_console"));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (data.postCommandData() != null) {
|
|
||||||
resetCommandScope(data.player(), data.postCommandData());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return CompletableFuture.completedFuture(true);
|
tp = true;
|
||||||
});
|
} else {
|
||||||
|
player.sendMessage(TranslatableCaption.of("border.denied"));
|
||||||
|
return CompletableFuture.completedFuture(false);
|
||||||
|
}
|
||||||
|
// Trim command
|
||||||
|
args = Arrays.copyOfRange(args, 1, args.length);
|
||||||
|
}
|
||||||
|
if (args.length >= 2 && !args[0].isEmpty() && args[0].charAt(0) == '-') {
|
||||||
|
if ("f".equals(args[0].substring(1))) {
|
||||||
|
confirm = new RunnableVal3<>() {
|
||||||
|
@Override
|
||||||
|
public void run(Command cmd, Runnable success, Runnable failure) {
|
||||||
|
if (area != null && PlotSquared.platform().econHandler().isEnabled(area)) {
|
||||||
|
PlotExpression priceEval =
|
||||||
|
area.getPrices().get(cmd.getFullId());
|
||||||
|
double price = priceEval != null ? priceEval.evaluate(0d) : 0d;
|
||||||
|
if (price != 0d
|
||||||
|
&& PlotSquared.platform().econHandler().getMoney(player) < price) {
|
||||||
|
if (failure != null) {
|
||||||
|
failure.run();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (success != null) {
|
||||||
|
success.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
args = Arrays.copyOfRange(args, 1, args.length);
|
||||||
|
} else {
|
||||||
|
player.sendMessage(TranslatableCaption.of("errors.invalid_command_flag"));
|
||||||
|
return CompletableFuture.completedFuture(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
super.execute(player, args, confirm, whenDone);
|
||||||
|
} catch (CommandException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
String message = e.getMessage();
|
||||||
|
if (message != null) {
|
||||||
|
player.sendMessage(
|
||||||
|
TranslatableCaption.of("errors.error"),
|
||||||
|
TagResolver.resolver("value", Tag.inserting(Component.text(message)))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
player.sendMessage(
|
||||||
|
TranslatableCaption.of("errors.error_console"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Reset command scope //
|
||||||
|
if (tp && !(player instanceof ConsolePlayer)) {
|
||||||
|
try (final MetaDataAccess<Location> locationMetaDataAccess
|
||||||
|
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
|
||||||
|
if (location == null) {
|
||||||
|
locationMetaDataAccess.remove();
|
||||||
|
} else {
|
||||||
|
locationMetaDataAccess.set(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try (final MetaDataAccess<Plot> plotMetaDataAccess
|
||||||
|
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
|
||||||
|
if (plot == null) {
|
||||||
|
plotMetaDataAccess.remove();
|
||||||
|
} else {
|
||||||
|
plotMetaDataAccess.set(plot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return CompletableFuture.completedFuture(true);
|
return CompletableFuture.completedFuture(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<Optional<CommandExecutionData>> prepareArguments(CommandExecutionData data) {
|
|
||||||
if (data.args().length >= 2) {
|
|
||||||
PlotArea area = data.player().getApplicablePlotArea();
|
|
||||||
Plot newPlot = Plot.fromString(area, data.args()[0]);
|
|
||||||
return preparePlotArgument(newPlot, data, area)
|
|
||||||
.thenApply(d -> d.flatMap(x -> prepareFlagArgument(x, area)));
|
|
||||||
} else {
|
|
||||||
return CompletableFuture.completedFuture(Optional.of(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompletableFuture<Optional<CommandExecutionData>> preparePlotArgument(@Nullable Plot newPlot,
|
|
||||||
@Nonnull CommandExecutionData data,
|
|
||||||
@Nullable PlotArea area) {
|
|
||||||
if (newPlot != null && (data.player() instanceof ConsolePlayer
|
|
||||||
|| (area != null && area.equals(newPlot.getArea()))
|
|
||||||
|| data.player().hasPermission(Permission.PERMISSION_ADMIN)
|
|
||||||
|| data.player().hasPermission(Permission.PERMISSION_ADMIN_AREA_SUDO))
|
|
||||||
&& !newPlot.isDenied(data.player().getUUID())) {
|
|
||||||
return fetchPlotCenterLocation(newPlot)
|
|
||||||
.thenApply(newLoc -> {
|
|
||||||
if (!data.player().canTeleport(newLoc)) {
|
|
||||||
data.player().sendMessage(TranslatableCaption.of("border.denied"));
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
// Save meta
|
|
||||||
var originalCommandMeta = setCommandScope(data.player(), new TemporaryCommandMeta(newLoc, newPlot));
|
|
||||||
return Optional.of(new CommandExecutionData(
|
|
||||||
data.player(),
|
|
||||||
Arrays.copyOfRange(data.args(), 1, data.args().length), // Trimmed command
|
|
||||||
data.confirm(),
|
|
||||||
data.whenDone(),
|
|
||||||
originalCommandMeta
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return CompletableFuture.completedFuture(Optional.of(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<CommandExecutionData> prepareFlagArgument(@Nonnull CommandExecutionData data, @Nonnull PlotArea area) {
|
|
||||||
if (data.args().length >= 2 && !data.args()[0].isEmpty() && data.args()[0].charAt(0) == '-') {
|
|
||||||
if ("f".equals(data.args()[0].substring(1))) {
|
|
||||||
return Optional.of(new CommandExecutionData(
|
|
||||||
data.player(),
|
|
||||||
Arrays.copyOfRange(data.args(), 1, data.args().length), // Trimmed command
|
|
||||||
createForcedConfirmation(data.player(), area),
|
|
||||||
data.whenDone(),
|
|
||||||
data.postCommandData()
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
data.player().sendMessage(TranslatableCaption.of("errors.invalid_command_flag"));
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.of(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompletableFuture<Location> fetchPlotCenterLocation(Plot plot) {
|
|
||||||
if (plot.getArea() instanceof SinglePlotArea && !plot.isLoaded()) {
|
|
||||||
return CompletableFuture.completedFuture(Location.at("", 0, 0, 0));
|
|
||||||
}
|
|
||||||
CompletableFuture<Location> future = new CompletableFuture<>();
|
|
||||||
plot.getCenter(future::complete);
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
|
|
||||||
private @Nonnull RunnableVal3<Command, Runnable, Runnable> createForcedConfirmation(@Nonnull PlotPlayer<?> player,
|
|
||||||
@Nullable PlotArea area) {
|
|
||||||
return new RunnableVal3<>() {
|
|
||||||
@Override
|
|
||||||
public void run(Command cmd, Runnable success, Runnable failure) {
|
|
||||||
if (area != null && PlotSquared.platform().econHandler().isEnabled(area)
|
|
||||||
&& Optional.of(area.getPrices().get(cmd.getFullId()))
|
|
||||||
.map(priceEval -> priceEval.evaluate(0d))
|
|
||||||
.filter(price -> price != 0d)
|
|
||||||
.filter(price -> PlotSquared.platform().econHandler().getMoney(player) < price)
|
|
||||||
.isPresent()) {
|
|
||||||
if (failure != null) {
|
|
||||||
failure.run();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (success != null) {
|
|
||||||
success.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private @Nonnull TemporaryCommandMeta setCommandScope(@Nonnull PlotPlayer<?> player, @Nonnull TemporaryCommandMeta commandMeta) {
|
|
||||||
Objects.requireNonNull(commandMeta.location());
|
|
||||||
Objects.requireNonNull(commandMeta.plot());
|
|
||||||
Location location;
|
|
||||||
Plot plot;
|
|
||||||
try (final MetaDataAccess<Location> locationMetaDataAccess
|
|
||||||
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
|
|
||||||
location = locationMetaDataAccess.get().orElse(null);
|
|
||||||
locationMetaDataAccess.set(commandMeta.location());
|
|
||||||
}
|
|
||||||
try (final MetaDataAccess<Plot> plotMetaDataAccess
|
|
||||||
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
|
|
||||||
plot = plotMetaDataAccess.get().orElse(null);
|
|
||||||
plotMetaDataAccess.set(commandMeta.plot());
|
|
||||||
}
|
|
||||||
return new TemporaryCommandMeta(location, plot);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetCommandScope(@Nonnull PlotPlayer<?> player, @Nonnull TemporaryCommandMeta commandMeta) {
|
|
||||||
try (final MetaDataAccess<Location> locationMetaDataAccess
|
|
||||||
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
|
|
||||||
if (commandMeta.location() == null) {
|
|
||||||
locationMetaDataAccess.remove();
|
|
||||||
} else {
|
|
||||||
locationMetaDataAccess.set(commandMeta.location());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try (final MetaDataAccess<Plot> plotMetaDataAccess
|
|
||||||
= player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
|
|
||||||
if (commandMeta.plot() == null) {
|
|
||||||
plotMetaDataAccess.remove();
|
|
||||||
} else {
|
|
||||||
plotMetaDataAccess.set(commandMeta.plot());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private record CommandExecutionData(@Nonnull PlotPlayer<?> player, @Nonnull String[] args,
|
|
||||||
@Nonnull RunnableVal3<Command, Runnable, Runnable> confirm,
|
|
||||||
@Nonnull RunnableVal2<Command, CommandResult> whenDone,
|
|
||||||
@Nullable TemporaryCommandMeta postCommandData) {}
|
|
||||||
|
|
||||||
private record TemporaryCommandMeta(@Nullable Location location, @Nullable Plot plot) {}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canExecute(PlotPlayer<?> player, boolean message) {
|
public boolean canExecute(PlotPlayer<?> player, boolean message) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -22,7 +22,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "com.intellectualsites.plotsquared"
|
group = "com.intellectualsites.plotsquared"
|
||||||
version = "7.5.2"
|
version = "7.5.2-SNAPSHOT"
|
||||||
|
|
||||||
if (!File("$rootDir/.git").exists()) {
|
if (!File("$rootDir/.git").exists()) {
|
||||||
logger.lifecycle("""
|
logger.lifecycle("""
|
||||||
@ -79,8 +79,8 @@ subprojects {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Tests
|
// Tests
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.12.1")
|
testImplementation("org.junit.jupiter:junit-jupiter:5.12.0")
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.12.1")
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.12.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins.withId("java") {
|
plugins.withId("java") {
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
# Platform expectations
|
# Platform expectations
|
||||||
paper = "1.20.4-R0.1-SNAPSHOT"
|
paper = "1.20.4-R0.1-SNAPSHOT"
|
||||||
guice = "7.0.0"
|
guice = "7.0.0"
|
||||||
spotbugs = "4.9.3"
|
spotbugs = "4.9.1"
|
||||||
checkerqual = "3.49.2"
|
checkerqual = "3.49.0"
|
||||||
gson = "2.10"
|
gson = "2.10"
|
||||||
guava = "31.1-jre"
|
guava = "31.1-jre"
|
||||||
snakeyaml = "2.0"
|
snakeyaml = "2.0"
|
||||||
adventure = "4.20.0"
|
adventure = "4.19.0"
|
||||||
adventure-bukkit = "4.3.4"
|
adventure-bukkit = "4.3.4"
|
||||||
log4j = "2.19.0"
|
log4j = "2.19.0"
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ worldedit = "7.2.20"
|
|||||||
fawe = "2.13.0"
|
fawe = "2.13.0"
|
||||||
placeholderapi = "2.11.6"
|
placeholderapi = "2.11.6"
|
||||||
luckperms = "5.4"
|
luckperms = "5.4"
|
||||||
essentialsx = "2.21.0"
|
essentialsx = "2.20.1"
|
||||||
mvdwapi = "3.1.1"
|
mvdwapi = "3.1.1"
|
||||||
|
|
||||||
# Third party
|
# Third party
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
2
gradlew
vendored
2
gradlew
vendored
@ -205,7 +205,7 @@ fi
|
|||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command:
|
# Collect all arguments for the java command:
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
# and any embedded shellness will be escaped.
|
# and any embedded shellness will be escaped.
|
||||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
# treated as '${Hostname}' itself on the command line.
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
Reference in New Issue
Block a user