Features/v5/move swap fixes + some other important commits (comments, etc) (#2699)

* Use generics instead of the raw class

* Add Gradle wrapper verification

* Fix biome setting in versions prior to 1.15

* Fixes #2654

* Document area getters in PlotAreaManager, and replace y-value with z in the area contains check.

* Remove update notifications

* Remove unused dependencies

* Do not kick plot owners on "/p deny *"

* Do not kick any added players on /p deny *

* Allow redstone to be used in server plot with `redstone.disable-offline` enabled.

Potentially fixes #2613

* Disallow swapping ,erged plots

* Fix legacy converter.

* Fix blockbucket pattern generation

* Prevent pasting schematics onto merged plots.

* Cancel claim event correctly

* Revert "Cancel claim event correctly"

This reverts commit 0f786155
Further investigation required

* Fix plot swapping messing up owners. Fixes #2282

* Fix plot move

* Prevent plot swapping form changing the database unless the swap was successful.

* Update signs after swap.

* Only send move success message if the move was successful.

Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
Co-authored-by: NotMyFault <mc.cache@web.de>
Co-authored-by: Daniel <admin@hywse.eu>
Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com>
This commit is contained in:
Alexander Söderberg 2020-02-28 22:15:04 +01:00 committed by GitHub
parent 30b83faab6
commit 05626c2c8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 325 additions and 199 deletions

View File

@ -22,5 +22,7 @@ jobs:
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: 1.8 java-version: 1.8
- name: Gradle Wrapper Validation
uses: gradle/wrapper-validation-action@v1
- name: Test with Gradle - name: Test with Gradle
run: ./gradlew clean build run: ./gradlew clean build

View File

@ -7,6 +7,7 @@ import com.github.intellectualsites.plotsquared.bukkit.util.UpdateUtility;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.Captions; import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.database.DBFunc;
import com.github.intellectualsites.plotsquared.plot.flags.implementations.AnimalAttackFlag; import com.github.intellectualsites.plotsquared.plot.flags.implementations.AnimalAttackFlag;
import com.github.intellectualsites.plotsquared.plot.flags.implementations.AnimalCapFlag; import com.github.intellectualsites.plotsquared.plot.flags.implementations.AnimalCapFlag;
import com.github.intellectualsites.plotsquared.plot.flags.implementations.AnimalInteractFlag; import com.github.intellectualsites.plotsquared.plot.flags.implementations.AnimalInteractFlag;
@ -485,17 +486,19 @@ import java.util.regex.Pattern;
return; return;
} }
if (Settings.Redstone.DISABLE_OFFLINE) { if (Settings.Redstone.DISABLE_OFFLINE) {
boolean disable; boolean disable = false;
if (plot.isMerged()) { if (!plot.getOwner().equals(DBFunc.SERVER)) {
disable = true; if (plot.isMerged()) {
for (UUID owner : plot.getOwners()) { disable = true;
if (UUIDHandler.getPlayer(owner) != null) { for (UUID owner : plot.getOwners()) {
disable = false; if (UUIDHandler.getPlayer(owner) != null) {
break; disable = false;
break;
}
} }
} else {
disable = UUIDHandler.getPlayer(plot.guessOwner()) == null;
} }
} else {
disable = UUIDHandler.getPlayer(plot.guessOwner()) == null;
} }
if (disable) { if (disable) {
for (UUID trusted : plot.getTrusted()) { for (UUID trusted : plot.getTrusted()) {

View File

@ -39,6 +39,7 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -46,6 +47,14 @@ import java.util.Set;
@SuppressWarnings({"unused", "WeakerAccess"}) public class BukkitUtil extends WorldUtil { @SuppressWarnings({"unused", "WeakerAccess"}) public class BukkitUtil extends WorldUtil {
private static Method biomeSetter;
static {
try {
biomeSetter = World.class.getMethod("setBiome", Integer.class, Integer.class, Biome.class);
} catch (final Exception ignored) {
}
}
private static String lastString = null; private static String lastString = null;
private static World lastWorld = null; private static World lastWorld = null;
@ -425,7 +434,16 @@ import java.util.Set;
for (int x = region.getMinimumPoint().getX(); x <= region.getMaximumPoint().getX(); x++) { for (int x = region.getMinimumPoint().getX(); x <= region.getMaximumPoint().getX(); x++) {
for (int z = region.getMinimumPoint().getZ(); z <= region.getMaximumPoint().getZ(); z++) { for (int z = region.getMinimumPoint().getZ(); z <= region.getMaximumPoint().getZ(); z++) {
for (int y = 0; y < world.getMaxHeight(); y++) { for (int y = 0; y < world.getMaxHeight(); y++) {
world.setBiome(x, y, z, biome); try {
if (biomeSetter != null) {
biomeSetter.invoke(world, x, z, biome);
} else {
world.setBiome(x, y, z, biome);
}
} catch (final Exception e) {
PlotSquared.log("An error occurred setting the biome:");
e.printStackTrace();
}
} }
} }
} }

View File

@ -7,6 +7,7 @@ import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.world.PatternUtil; import com.github.intellectualsites.plotsquared.plot.util.world.PatternUtil;
import com.google.common.base.Preconditions;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
@ -20,9 +21,9 @@ import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator.BiomeGrid; import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.generator.ChunkGenerator.ChunkData; import org.bukkit.generator.ChunkGenerator.ChunkData;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays; import java.util.Arrays;
import org.jetbrains.annotations.NotNull;
public class GenChunk extends ScopedLocalBlockQueue { public class GenChunk extends ScopedLocalBlockQueue {
@ -109,7 +110,7 @@ public class GenChunk extends ScopedLocalBlockQueue {
} }
@Override public boolean setBlock(int x, int y, int z, @NotNull Pattern pattern) { @Override public boolean setBlock(int x, int y, int z, @NotNull Pattern pattern) {
return setBlock(x, y, z, PatternUtil.apply(pattern, x, y, z)); return setBlock(x, y, z, PatternUtil.apply(Preconditions.checkNotNull(pattern, "Pattern may not be null"), x, y, z));
} }
@Override public boolean setBlock(int x, int y, int z, BlockState id) { @Override public boolean setBlock(int x, int y, int z, BlockState id) {

View File

@ -2,9 +2,7 @@ package com.github.intellectualsites.plotsquared.plot.commands;
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
import com.github.intellectualsites.plotsquared.plot.config.Captions; import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.object.comment.CommentInbox; import com.github.intellectualsites.plotsquared.plot.object.comment.CommentInbox;
import com.github.intellectualsites.plotsquared.plot.object.comment.PlotComment; import com.github.intellectualsites.plotsquared.plot.object.comment.PlotComment;
@ -14,6 +12,7 @@ import com.github.intellectualsites.plotsquared.plot.util.StringMan;
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale;
import java.util.Map.Entry; import java.util.Map.Entry;
@CommandDeclaration(command = "comment", @CommandDeclaration(command = "comment",
@ -30,40 +29,41 @@ public class Comment extends SubCommand {
StringMan.join(CommentManager.inboxes.keySet(), "|")); StringMan.join(CommentManager.inboxes.keySet(), "|"));
return false; return false;
} }
CommentInbox inbox = CommentManager.inboxes.get(args[0].toLowerCase());
if (inbox == null) { // Attempt to extract a plot out of the first argument
sendMessage(player, Captions.COMMENT_SYNTAX, Plot plot = null;
StringMan.join(CommentManager.inboxes.keySet(), "|")); if (!CommentManager.inboxes.containsKey(args[0].toLowerCase(Locale.ENGLISH))) {
return false; plot = MainUtil.getPlotFromString(player, args[0], false);
} }
Location location = player.getLocation();
PlotId id;
try {
id = PlotId.fromString(args[1]);
} catch (IllegalArgumentException ignored) {
MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID);
return false;
}
Plot plot = MainUtil.getPlotFromString(player, args[1], false);
int index; int index;
if (plot == null) { if (plot == null) {
index = 1; index = 1;
plot = location.getPlotAbs(); plot = player.getLocation().getPlotAbs();
} else { } else {
if (args.length < 4) { if (args.length < 3) {
sendMessage(player, Captions.COMMENT_SYNTAX, sendMessage(player, Captions.COMMENT_SYNTAX,
StringMan.join(CommentManager.inboxes.keySet(), "|")); StringMan.join(CommentManager.inboxes.keySet(), "|"));
return false; return false;
} }
index = 2; index = 2;
} }
CommentInbox inbox = CommentManager.inboxes.get(args[index - 1].toLowerCase());
if (inbox == null) {
sendMessage(player, Captions.COMMENT_SYNTAX,
StringMan.join(CommentManager.inboxes.keySet(), "|"));
return false;
}
if (!inbox.canWrite(plot, player)) { if (!inbox.canWrite(plot, player)) {
sendMessage(player, Captions.NO_PERM_INBOX, ""); sendMessage(player, Captions.NO_PERM_INBOX, "");
return false; return false;
} }
String message = StringMan.join(Arrays.copyOfRange(args, index, args.length), " "); String message = StringMan.join(Arrays.copyOfRange(args, index, args.length), " ");
PlotComment comment = PlotComment comment =
new PlotComment(location.getWorld(), id, message, player.getName(), inbox.toString(), new PlotComment(player.getLocation().getWorld(), plot.getId(), message, player.getName(), inbox.toString(),
System.currentTimeMillis()); System.currentTimeMillis());
boolean result = inbox.addComment(plot, comment); boolean result = inbox.addComment(plot, comment);
if (!result) { if (!result) {

View File

@ -17,6 +17,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@CommandDeclaration(command = "condense", @CommandDeclaration(command = "condense",
@ -135,13 +136,17 @@ public class Condense extends SubCommand {
} }
i++; i++;
final AtomicBoolean result = new AtomicBoolean(false); final AtomicBoolean result = new AtomicBoolean(false);
result.set(origin.move(possible, () -> { try {
if (result.get()) { result.set(origin.move(possible, () -> {
MainUtil.sendMessage(player, if (result.get()) {
"Moving: " + origin + " -> " + possible); MainUtil.sendMessage(player,
TaskManager.runTaskLater(task, 1); "Moving: " + origin + " -> " + possible);
} TaskManager.runTaskLater(task, 1);
}, false)); }
}, false).get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
if (result.get()) { if (result.get()) {
break; break;
} }

View File

@ -77,6 +77,10 @@ public class Deny extends SubCommand {
handleKick(UUIDHandler.getPlayer(uuid), plot); handleKick(UUIDHandler.getPlayer(uuid), plot);
} else { } else {
for (PlotPlayer plotPlayer : plot.getPlayersInPlot()) { for (PlotPlayer plotPlayer : plot.getPlayersInPlot()) {
// Ignore plot-owners
if (plot.isAdded(plotPlayer.getUUID())) {
continue;
}
handleKick(plotPlayer, plot); handleKick(plotPlayer, plot);
} }
} }

View File

@ -1,5 +1,6 @@
package com.github.intellectualsites.plotsquared.plot.commands; package com.github.intellectualsites.plotsquared.plot.commands;
import com.github.intellectualsites.plotsquared.commands.Command;
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.Captions; import com.github.intellectualsites.plotsquared.plot.config.Captions;
@ -7,9 +8,13 @@ import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea; import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal2;
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal3;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.Permissions; import com.github.intellectualsites.plotsquared.plot.util.Permissions;
import java.util.concurrent.CompletableFuture;
@CommandDeclaration(usage = "/plot move <X;Z>", @CommandDeclaration(usage = "/plot move <X;Z>",
command = "move", command = "move",
description = "Move a plot", description = "Move a plot",
@ -18,16 +23,19 @@ import com.github.intellectualsites.plotsquared.plot.util.Permissions;
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Move extends SubCommand { public class Move extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) {
Location location = player.getLocation(); Location location = player.getLocation();
Plot plot1 = location.getPlotAbs(); Plot plot1 = location.getPlotAbs();
if (plot1 == null) { if (plot1 == null) {
return !MainUtil.sendMessage(player, Captions.NOT_IN_PLOT); return CompletableFuture
.completedFuture(!MainUtil.sendMessage(player, Captions.NOT_IN_PLOT));
} }
if (!plot1.isOwner(player.getUUID()) && !Permissions if (!plot1.isOwner(player.getUUID()) && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN.getTranslated())) { .hasPermission(player, Captions.PERMISSION_ADMIN.getTranslated())) {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS); MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false; return CompletableFuture.completedFuture(false);
} }
boolean override = false; boolean override = false;
if (args.length == 2 && args[1].equalsIgnoreCase("-f")) { if (args.length == 2 && args[1].equalsIgnoreCase("-f")) {
@ -36,14 +44,14 @@ public class Move extends SubCommand {
} }
if (args.length != 1) { if (args.length != 1) {
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
return false; return CompletableFuture.completedFuture(false);
} }
PlotArea area = PlotSquared.get().getPlotAreaByString(args[0]); PlotArea area = PlotSquared.get().getPlotAreaByString(args[0]);
Plot plot2; Plot plot2;
if (area == null) { if (area == null) {
plot2 = MainUtil.getPlotFromString(player, args[0], true); plot2 = MainUtil.getPlotFromString(player, args[0], true);
if (plot2 == null) { if (plot2 == null) {
return false; return CompletableFuture.completedFuture(false);
} }
} else { } else {
plot2 = area.getPlotAbs(plot1.getId()); plot2 = area.getPlotAbs(plot1.getId());
@ -51,19 +59,32 @@ public class Move extends SubCommand {
if (plot1.equals(plot2)) { if (plot1.equals(plot2)) {
MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID); MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID);
MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX, "/plot copy <X;Z>"); MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX, "/plot copy <X;Z>");
return false; return CompletableFuture.completedFuture(false);
} }
if (!plot1.getArea().isCompatible(plot2.getArea()) && (!override || !Permissions if (!plot1.getArea().isCompatible(plot2.getArea()) && (!override || !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN.getTranslated()))) { .hasPermission(player, Captions.PERMISSION_ADMIN.getTranslated()))) {
Captions.PLOTWORLD_INCOMPATIBLE.send(player); Captions.PLOTWORLD_INCOMPATIBLE.send(player);
return false; return CompletableFuture.completedFuture(false);
} }
if (plot1.move(plot2, () -> MainUtil.sendMessage(player, Captions.MOVE_SUCCESS), false)) { if (plot1.isMerged() || plot2.isMerged()) {
return true; Captions.MOVE_MERGED.send(player);
} else { return CompletableFuture.completedFuture(false);
MainUtil.sendMessage(player, Captions.REQUIRES_UNOWNED);
return false;
} }
return plot1.move(plot2, () -> {}, false)
.thenApply(result -> {
if (result) {
MainUtil.sendMessage(player, Captions.MOVE_SUCCESS);
return true;
} else {
MainUtil.sendMessage(player, Captions.REQUIRES_UNOWNED);
return false;
}
});
}
@Override public boolean onCommand(final PlotPlayer player, String[] args) {
return true;
} }
} }

View File

@ -68,6 +68,10 @@ public class SchematicCmd extends SubCommand {
MainUtil.sendMessage(player, Captions.TASK_IN_PROCESS); MainUtil.sendMessage(player, Captions.TASK_IN_PROCESS);
return false; return false;
} }
if (plot.isMerged()) {
MainUtil.sendMessage(player, Captions.SCHEMATIC_PASTE_MERGED);
return false;
}
final String location = args[1]; final String location = args[1];
this.running = true; this.running = true;
TaskManager.runTaskAsync(() -> { TaskManager.runTaskAsync(() -> {

View File

@ -1,13 +1,18 @@
package com.github.intellectualsites.plotsquared.plot.commands; package com.github.intellectualsites.plotsquared.plot.commands;
import com.github.intellectualsites.plotsquared.commands.Command;
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
import com.github.intellectualsites.plotsquared.plot.config.Captions; import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.object.Location; import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal2;
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal3;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.Permissions; import com.github.intellectualsites.plotsquared.plot.util.Permissions;
import java.util.concurrent.CompletableFuture;
@CommandDeclaration(usage = "/plot swap <X;Z>", @CommandDeclaration(usage = "/plot swap <X;Z>",
command = "swap", command = "swap",
description = "Swap two plots", description = "Swap two plots",
@ -16,43 +21,54 @@ import com.github.intellectualsites.plotsquared.plot.util.Permissions;
requiredType = RequiredType.PLAYER) requiredType = RequiredType.PLAYER)
public class Swap extends SubCommand { public class Swap extends SubCommand {
@Override public boolean onCommand(final PlotPlayer player, String[] args) { @Override public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) {
Location location = player.getLocation(); Location location = player.getLocation();
Plot plot1 = location.getPlotAbs(); Plot plot1 = location.getPlotAbs();
if (plot1 == null) { if (plot1 == null) {
return !MainUtil.sendMessage(player, Captions.NOT_IN_PLOT); return CompletableFuture.completedFuture(!MainUtil.sendMessage(player, Captions.NOT_IN_PLOT));
} }
if (!plot1.isOwner(player.getUUID()) && !Permissions if (!plot1.isOwner(player.getUUID()) && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN.getTranslated())) { .hasPermission(player, Captions.PERMISSION_ADMIN.getTranslated())) {
MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS); MainUtil.sendMessage(player, Captions.NO_PLOT_PERMS);
return false; return CompletableFuture.completedFuture(false);
} }
if (args.length != 1) { if (args.length != 1) {
Captions.COMMAND_SYNTAX.send(player, getUsage()); Captions.COMMAND_SYNTAX.send(player, getUsage());
return false; return CompletableFuture.completedFuture(false);
} }
Plot plot2 = MainUtil.getPlotFromString(player, args[0], true); Plot plot2 = MainUtil.getPlotFromString(player, args[0], true);
if (plot2 == null) { if (plot2 == null) {
return false; return CompletableFuture.completedFuture(false);
} }
if (plot1.equals(plot2)) { if (plot1.equals(plot2)) {
MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID); MainUtil.sendMessage(player, Captions.NOT_VALID_PLOT_ID);
MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX, "/plot copy <X;Z>"); MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX, "/plot copy <X;Z>");
return false; return CompletableFuture.completedFuture(false);
} }
if (!plot1.getArea().isCompatible(plot2.getArea())) { if (!plot1.getArea().isCompatible(plot2.getArea())) {
Captions.PLOTWORLD_INCOMPATIBLE.send(player); Captions.PLOTWORLD_INCOMPATIBLE.send(player);
return false; return CompletableFuture.completedFuture(false);
} }
if (plot1.move(plot2, new Runnable() { if (plot1.isMerged() || plot2.isMerged()) {
@Override public void run() { Captions.SWAP_MERGED.send(player);
MainUtil.sendMessage(player, Captions.SWAP_SUCCESS); return CompletableFuture.completedFuture(false);
}
}, true)) {
return true;
} else {
MainUtil.sendMessage(player, Captions.SWAP_OVERLAP);
return false;
} }
return plot1.move(plot2, () -> {}, true)
.thenApply(result -> {
if (result) {
MainUtil.sendMessage(player, Captions.SWAP_SUCCESS);
return true;
} else {
MainUtil.sendMessage(player, Captions.SWAP_OVERLAP);
return false;
}
});
}
@Override public boolean onCommand(final PlotPlayer player, String[] args) {
return true;
} }
} }

View File

@ -174,6 +174,7 @@ public enum Captions implements Caption {
//</editor-fold> //</editor-fold>
//<editor-fold desc="Move"> //<editor-fold desc="Move">
MOVE_SUCCESS("$4Successfully moved plot.", "Move"), MOVE_SUCCESS("$4Successfully moved plot.", "Move"),
MOVE_MERGED("$2Merged plots may not be moved. Please unmerge the plot before performing the move.", "Move"),
COPY_SUCCESS("$4Successfully copied plot.", "Move"), COPY_SUCCESS("$4Successfully copied plot.", "Move"),
REQUIRES_UNOWNED("$2The location specified is already occupied.", "Move"), REQUIRES_UNOWNED("$2The location specified is already occupied.", "Move"),
//</editor-fold> //</editor-fold>
@ -234,6 +235,7 @@ public enum Captions implements Caption {
SWAP_DIMENSIONS("$2The proposed areas must have comparable dimensions", "Swap"), SWAP_DIMENSIONS("$2The proposed areas must have comparable dimensions", "Swap"),
SWAP_SYNTAX("$2/plot swap <id>", "Swap"), SWAP_SYNTAX("$2/plot swap <id>", "Swap"),
SWAP_SUCCESS("$4Successfully swapped plots", "Swap"), SWAP_SUCCESS("$4Successfully swapped plots", "Swap"),
SWAP_MERGED("$2Merged plots may not be swapped. Please unmerge the plot before performing the swap.", "Swap"),
//</editor-fold> //</editor-fold>
//<editor-fold desc="Comments"> //<editor-fold desc="Comments">
INBOX_NOTIFICATION("%s unread messages. Use /plot inbox", "Comment"), INBOX_NOTIFICATION("%s unread messages. Use /plot inbox", "Comment"),
@ -318,6 +320,7 @@ public enum Captions implements Caption {
SCHEMATIC_MISSING_ARG("$2You need to specify an argument. Possible values: $1save$2, $1paste $2, $1exportall$2, $1list", "Schematics"), SCHEMATIC_MISSING_ARG("$2You need to specify an argument. Possible values: $1save$2, $1paste $2, $1exportall$2, $1list", "Schematics"),
SCHEMATIC_INVALID("$2That is not a valid schematic. Reason: $2%s", "Schematics"), SCHEMATIC_INVALID("$2That is not a valid schematic. Reason: $2%s", "Schematics"),
SCHEMATIC_VALID("$2That is a valid schematic", "Schematics"), SCHEMATIC_VALID("$2That is a valid schematic", "Schematics"),
SCHEMATIC_PASTE_MERGED("$2Schematics cannot be pasted onto merged plots. Please unmerge the plot before performing the paste.", "Schematics"),
SCHEMATIC_PASTE_FAILED("$2Failed to paste the schematic", "Schematics"), SCHEMATIC_PASTE_FAILED("$2Failed to paste the schematic", "Schematics"),
SCHEMATIC_PASTE_SUCCESS("$4The schematic pasted successfully", "Schematics"), SCHEMATIC_PASTE_SUCCESS("$4The schematic pasted successfully", "Schematics"),
SCHEMATIC_LIST("$4Saved Schematics: $1%s", "Schematics"), SCHEMATIC_LIST("$4Saved Schematics: $1%s", "Schematics"),

View File

@ -3,6 +3,7 @@ package com.github.intellectualsites.plotsquared.plot.config;
import com.github.intellectualsites.plotsquared.configuration.MemorySection; import com.github.intellectualsites.plotsquared.configuration.MemorySection;
import com.github.intellectualsites.plotsquared.configuration.file.YamlConfiguration; import com.github.intellectualsites.plotsquared.configuration.file.YamlConfiguration;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.Settings.Enabled_Components;
import com.github.intellectualsites.plotsquared.plot.util.StringMan; import com.github.intellectualsites.plotsquared.plot.util.StringMan;
import java.io.File; import java.io.File;
@ -30,7 +31,7 @@ public class Config {
* @param <T> * @param <T>
* @return * @return
*/ */
public static <T> T get(String key, Class root) { public static <T> T get(String key, Class<?> root) {
String[] split = key.split("\\."); String[] split = key.split("\\.");
Object instance = getInstance(split, root); Object instance = getInstance(split, root);
if (instance != null) { if (instance != null) {
@ -55,7 +56,7 @@ public class Config {
* @param value value * @param value value
* @param root * @param root
*/ */
public static void set(String key, Object value, Class root) { public static void set(String key, Object value, Class<? extends Config> root) {
String[] split = key.split("\\."); String[] split = key.split("\\.");
Object instance = getInstance(split, root); Object instance = getInstance(split, root);
if (instance != null) { if (instance != null) {
@ -81,7 +82,7 @@ public class Config {
PlotSquared.debug("Failed to set config option: " + key + ": " + value + " | " + instance); PlotSquared.debug("Failed to set config option: " + key + ": " + value + " | " + instance);
} }
public static boolean load(File file, Class root) { public static boolean load(File file, Class<? extends Config> root) {
if (!file.exists()) { if (!file.exists()) {
return false; return false;
} }
@ -102,7 +103,7 @@ public class Config {
* @param file * @param file
* @param root * @param root
*/ */
public static void save(File file, Class root) { public static void save(File file, Class<? extends Config> root) {
try { try {
if (!file.exists()) { if (!file.exists()) {
file.getParentFile().mkdirs(); file.getParentFile().mkdirs();
@ -123,7 +124,7 @@ public class Config {
* @param clazz * @param clazz
* @return * @return
*/ */
public static Map<String, Object> getFields(Class clazz) { public static Map<String, Object> getFields(Class<Enabled_Components> clazz) {
HashMap<String, Object> map = new HashMap<>(); HashMap<String, Object> map = new HashMap<>();
for (Field field : clazz.getFields()) { for (Field field : clazz.getFields()) {
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) { if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
@ -242,7 +243,7 @@ public class Config {
* @param root * @param root
* @return * @return
*/ */
private static Field getField(String[] split, Class root) { private static Field getField(String[] split, Class<?> root) {
Object instance = getInstance(split, root); Object instance = getInstance(split, root);
if (instance == null) { if (instance == null) {
return null; return null;
@ -278,7 +279,7 @@ public class Config {
* @param root * @param root
* @return The instance or null * @return The instance or null
*/ */
private static Object getInstance(String[] split, Class root) { private static Object getInstance(String[] split, Class<?> root) {
try { try {
Class<?> clazz = root == null ? MethodHandles.lookup().lookupClass() : root; Class<?> clazz = root == null ? MethodHandles.lookup().lookupClass() : root;
Object instance = clazz.newInstance(); Object instance = clazz.newInstance();
@ -286,9 +287,9 @@ public class Config {
if (split.length == 1) { if (split.length == 1) {
return instance; return instance;
} }
Class found = null; Class<?> found = null;
Class<?>[] classes = clazz.getDeclaredClasses(); Class<?>[] classes = clazz.getDeclaredClasses();
for (Class current : classes) { for (Class<?> current : classes) {
if (current.getSimpleName().equalsIgnoreCase(toFieldName(split[0]))) { if (current.getSimpleName().equalsIgnoreCase(toFieldName(split[0]))) {
found = current; found = current;
break; break;
@ -361,8 +362,6 @@ public class Config {
* Set some field to be accessible. * Set some field to be accessible.
* *
* @param field * @param field
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/ */
private static void setAccessible(Field field) { private static void setAccessible(Field field) {
field.setAccessible(true); field.setAccessible(true);

View File

@ -14,6 +14,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public interface AbstractDB { public interface AbstractDB {
@ -144,7 +145,7 @@ public interface AbstractDB {
* @param plot1 Plot1 * @param plot1 Plot1
* @param plot2 Plot2 * @param plot2 Plot2
*/ */
void swapPlots(Plot plot1, Plot plot2); CompletableFuture<Boolean> swapPlots(Plot plot1, Plot plot2);
/** /**
* Sets plot flag. * Sets plot flag.

View File

@ -16,6 +16,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
/** /**
* Database Functions * Database Functions
@ -58,10 +59,11 @@ public class DBFunc {
} }
} }
public static void swapPlots(Plot plot1, Plot plot2) { public static CompletableFuture<Boolean> swapPlots(Plot plot1, Plot plot2) {
if (dbManager != null) { if (dbManager != null) {
dbManager.swapPlots(plot1, plot2); return dbManager.swapPlots(plot1, plot2);
} }
return CompletableFuture.completedFuture(false);
} }
public static boolean deleteTables() { public static boolean deleteTables() {

View File

@ -44,6 +44,7 @@ import java.util.Map.Entry;
import java.util.Queue; import java.util.Queue;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -2028,37 +2029,32 @@ import java.util.concurrent.atomic.AtomicInteger;
}); });
} }
@Override public void swapPlots(Plot plot1, Plot plot2) { @Override public CompletableFuture<Boolean> swapPlots(Plot plot1, Plot plot2) {
final int id1 = getId(plot1); final CompletableFuture<Boolean> future = new CompletableFuture<>();
final int id2 = getId(plot2); TaskManager.runTaskAsync(() -> {
final PlotId pos1 = plot1.getId(); final int id1 = getId(plot1);
final PlotId pos2 = plot2.getId(); final int id2 = getId(plot2);
addPlotTask(plot1, new UniqueStatement("swapPlots") { final PlotId pos1 = plot1.getId();
@Override public void set(PreparedStatement statement) throws SQLException { final PlotId pos2 = plot2.getId();
statement.setInt(1, pos2.x); try (final PreparedStatement preparedStatement = this.connection.prepareStatement("UPDATE `" + SQLManager.this.prefix
statement.setInt(2, pos2.y); + "plot` SET `plot_id_x` = ?, `plot_id_z` = ? WHERE `id` = ?")) {
statement.setInt(3, id1); preparedStatement.setInt(1, pos1.getX());
} preparedStatement.setInt(2, pos1.getY());
preparedStatement.setInt(3, id1);
@Override public PreparedStatement get() throws SQLException { preparedStatement.execute();
return SQLManager.this.connection.prepareStatement( preparedStatement.setInt(1, pos2.getX());
"UPDATE `" + SQLManager.this.prefix preparedStatement.setInt(2, pos2.getY());
+ "plot` SET `plot_id_x` = ?, `plot_id_z` = ? WHERE `id` = ?"); preparedStatement.setInt(3, id2);
} preparedStatement.execute();
}); } catch (final Exception e) {
addPlotTask(plot2, new UniqueStatement("swapPlots") { PlotSquared.log(Captions.PREFIX.getTranslated() + "Failed to persist swap of " + plot1 + " and " + plot2 + "!");
@Override public void set(PreparedStatement statement) throws SQLException { e.printStackTrace();
statement.setInt(1, pos1.x); future.complete(false);
statement.setInt(2, pos1.y); return;
statement.setInt(3, id2);
}
@Override public PreparedStatement get() throws SQLException {
return SQLManager.this.connection.prepareStatement(
"UPDATE `" + SQLManager.this.prefix
+ "plot` SET `plot_id_x` = ?, `plot_id_z` = ? WHERE `id` = ?");
} }
future.complete(true);
}); });
return future;
} }
@Override public void movePlot(final Plot original, final Plot newPlot) { @Override public void movePlot(final Plot original, final Plot newPlot) {

View File

@ -80,7 +80,7 @@ public final class BlockBucket implements ConfigurationSerializable {
if (chance == -1) if (chance == -1)
chance = 1; chance = 1;
String prefix = input.length() == 0 ? "" : ","; String prefix = input.length() == 0 ? "" : ",";
input.append(prefix).append(chance).append("%").append(prefix); input.append(prefix).append(block.toString()).append(":").append(chance);
this.compiled = false; this.compiled = false;
} }

View File

@ -54,13 +54,16 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -1742,26 +1745,19 @@ public class Plot {
* Swaps the settings for two plots. * Swaps the settings for two plots.
* *
* @param plot the plot to swap data with * @param plot the plot to swap data with
* @param whenDone the task to run at the end of this method. * @return Future containing the result
* @return
*/ */
public boolean swapData(Plot plot, Runnable whenDone) { public CompletableFuture<Boolean> swapData(Plot plot) {
if (this.owner == null) { if (this.owner == null) {
if (plot == null) { if (plot != null && plot.hasOwner()) {
return false; plot.moveData(this, null);
return CompletableFuture.completedFuture(true);
} }
if (plot.hasOwner()) { return CompletableFuture.completedFuture(false);
plot.moveData(this, whenDone);
return true;
}
return false;
} }
if (plot == null) { if (plot == null || plot.getOwner() == null) {
this.moveData(plot, whenDone); this.moveData(plot, null);
return true; return CompletableFuture.completedFuture(true);
} else if (plot.getOwner() == null) {
this.moveData(plot, whenDone);
return true;
} }
// Swap cached // Swap cached
PlotId temp = new PlotId(this.getId().x, this.getId().y); PlotId temp = new PlotId(this.getId().x, this.getId().y);
@ -1776,9 +1772,7 @@ public class Plot {
this.area.addPlotAbs(this); this.area.addPlotAbs(this);
plot.area.addPlotAbs(plot); plot.area.addPlotAbs(plot);
// Swap database // Swap database
DBFunc.swapPlots(plot, this); return DBFunc.swapPlots(plot, this);
TaskManager.runTaskLater(whenDone, 1);
return true;
} }
/** /**
@ -1911,10 +1905,10 @@ public class Plot {
* @param whenDone A task to run when finished, or null * @param whenDone A task to run when finished, or null
* @return boolean if swap was successful * @return boolean if swap was successful
* @see ChunkManager#swap(Location, Location, Location, Location, Runnable) to swap terrain * @see ChunkManager#swap(Location, Location, Location, Location, Runnable) to swap terrain
* @see this#swapData(Plot, Runnable) to swap plot settings * @see this#swapData(Plot) to swap plot settings
* @see this#swapData(Plot, Runnable) * @see this#swapData(Plot)
*/ */
public boolean swap(Plot destination, Runnable whenDone) { public CompletableFuture<Boolean> swap(Plot destination, Runnable whenDone) {
return this.move(destination, whenDone, true); return this.move(destination, whenDone, true);
} }
@ -1926,7 +1920,7 @@ public class Plot {
* @param whenDone A task to run when done, or null * @param whenDone A task to run when done, or null
* @return if the move was successful * @return if the move was successful
*/ */
public boolean move(Plot destination, Runnable whenDone) { public CompletableFuture<Boolean> move(Plot destination, Runnable whenDone) {
return this.move(destination, whenDone, false); return this.move(destination, whenDone, false);
} }
@ -3067,7 +3061,7 @@ public class Plot {
* @param allowSwap whether to swap plots * @param allowSwap whether to swap plots
* @return success * @return success
*/ */
public boolean move(final Plot destination, final Runnable whenDone, boolean allowSwap) { public CompletableFuture<Boolean> move(final Plot destination, final Runnable whenDone, boolean allowSwap) {
final PlotId offset = new PlotId(destination.getId().x - this.getId().x, final PlotId offset = new PlotId(destination.getId().x - this.getId().x,
destination.getId().y - this.getId().y); destination.getId().y - this.getId().y);
Location db = destination.getBottomAbs(); Location db = destination.getBottomAbs();
@ -3076,18 +3070,18 @@ public class Plot {
final int offsetZ = db.getZ() - ob.getZ(); final int offsetZ = db.getZ() - ob.getZ();
if (this.owner == null) { if (this.owner == null) {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, 1);
return false; return CompletableFuture.completedFuture(false);
} }
boolean occupied = false; AtomicBoolean occupied = new AtomicBoolean(false);
Set<Plot> plots = this.getConnectedPlots(); Set<Plot> plots = this.getConnectedPlots();
for (Plot plot : plots) { for (Plot plot : plots) {
Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y);
if (other.hasOwner()) { if (other.hasOwner()) {
if (!allowSwap) { if (!allowSwap) {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, 1);
return false; return CompletableFuture.completedFuture(false);
} }
occupied = true; occupied.set(true);
} else { } else {
plot.removeSign(); plot.removeSign();
} }
@ -3097,59 +3091,85 @@ public class Plot {
final ArrayDeque<CuboidRegion> regions = new ArrayDeque<>(this.getRegions()); final ArrayDeque<CuboidRegion> regions = new ArrayDeque<>(this.getRegions());
// move / swap data // move / swap data
final PlotArea originArea = getArea(); final PlotArea originArea = getArea();
for (Plot plot : plots) {
Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); final Iterator<Plot> plotIterator = plots.iterator();
plot.swapData(other, null);
} CompletableFuture<Boolean> future = null;
// copy terrain if (plotIterator.hasNext()) {
if (occupied) { while (plotIterator.hasNext()) {
Runnable swap = new Runnable() { final Plot plot = plotIterator.next();
@Override public void run() { final Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y);
if (regions.isEmpty()) { final CompletableFuture<Boolean> swapResult = plot.swapData(other);
TaskManager.runTask(whenDone); if (future == null) {
return; future = swapResult;
} } else {
CuboidRegion region = regions.poll(); future = future.thenCombine(swapResult, (fn, th) -> fn);
Location[] corners = MainUtil.getCorners(getWorldName(), region);
Location pos1 = corners[0];
Location pos2 = corners[1];
Location pos3 = pos1.clone().add(offsetX, 0, offsetZ);
Location pos4 = pos2.clone().add(offsetX, 0, offsetZ);
pos3.setWorld(destination.getWorldName());
pos4.setWorld(destination.getWorldName());
ChunkManager.manager.swap(pos1, pos2, pos3, pos4, this);
} }
}; }
swap.run();
} else { } else {
Runnable move = new Runnable() { future = CompletableFuture.completedFuture(true);
@Override public void run() {
if (regions.isEmpty()) {
Plot plot = destination.getRelative(0, 0);
for (Plot current : plot.getConnectedPlots()) {
getManager().claimPlot(current);
Plot originPlot = originArea.getPlotAbs(
new PlotId(current.id.x - offset.x, current.id.y - offset.y));
originPlot.getManager().unClaimPlot(originPlot, null);
}
plot.setSign();
TaskManager.runTask(whenDone);
return;
}
final Runnable task = this;
CuboidRegion region = regions.poll();
Location[] corners = MainUtil.getCorners(getWorldName(), region);
final Location pos1 = corners[0];
final Location pos2 = corners[1];
Location newPos = pos1.clone().add(offsetX, 0, offsetZ);
newPos.setWorld(destination.getWorldName());
ChunkManager.manager.copyRegion(pos1, pos2, newPos,
() -> ChunkManager.manager.regenerateRegion(pos1, pos2, false, task));
}
};
move.run();
} }
return true;
return future.thenApply(result -> {
if (!result) {
return false;
}
// copy terrain
if (occupied.get()) {
new Runnable() {
@Override public void run() {
if (regions.isEmpty()) {
// Update signs
destination.setSign();
Plot.this.setSign();
// Run final tasks
TaskManager.runTask(whenDone);
} else {
CuboidRegion region = regions.poll();
Location[] corners = MainUtil.getCorners(getWorldName(), region);
Location pos1 = corners[0];
Location pos2 = corners[1];
Location pos3 = pos1.clone().add(offsetX, 0, offsetZ);
Location pos4 = pos2.clone().add(offsetX, 0, offsetZ);
pos3.setWorld(destination.getWorldName());
pos4.setWorld(destination.getWorldName());
ChunkManager.manager.swap(pos1, pos2, pos3, pos4, this);
}
}
}.run();
} else {
new Runnable() {
@Override public void run() {
if (regions.isEmpty()) {
Plot plot = destination.getRelative(0, 0);
Plot originPlot = originArea.getPlotAbs(new PlotId(plot.id.x - offset.x, plot.id.y - offset.y));
final Runnable clearDone = () -> {
for (final Plot current : plot.getConnectedPlots()) {
getManager().claimPlot(current);
}
plot.setSign();
TaskManager.runTask(whenDone);
};
if (originPlot != null) {
originPlot.clear(false, true, clearDone);
} else {
clearDone.run();
}
return;
}
final Runnable task = this;
CuboidRegion region = regions.poll();
Location[] corners = MainUtil.getCorners(getWorldName(), region);
final Location pos1 = corners[0];
final Location pos2 = corners[1];
Location newPos = pos1.clone().add(offsetX, 0, offsetZ);
newPos.setWorld(destination.getWorldName());
ChunkManager.manager.copyRegion(pos1, pos2, newPos, task);
}
}.run();
}
return true;
});
} }
/** /**

View File

@ -5,6 +5,7 @@ import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.util.StringMan; import com.github.intellectualsites.plotsquared.plot.util.StringMan;
import com.github.intellectualsites.plotsquared.plot.util.area.QuadMap; import com.github.intellectualsites.plotsquared.plot.util.area.QuadMap;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -61,7 +62,7 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
if (areas == null) { if (areas == null) {
return null; return null;
} }
int y; int z;
int x; int x;
switch (areas.length) { switch (areas.length) {
case 1: case 1:
@ -74,9 +75,9 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
case 7: case 7:
case 8: case 8:
x = location.getX(); x = location.getX();
y = location.getY(); z = location.getZ();
for (PlotArea area : areas) { for (PlotArea area : areas) {
if (area.contains(x, y)) { if (area.contains(x, z)) {
return area; return area;
} }
} }
@ -139,7 +140,7 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
return null; return null;
} }
@Override public PlotArea getPlotArea(Location location) { @Override public PlotArea getPlotArea(@NotNull Location location) {
switch (this.plotAreas.length) { switch (this.plotAreas.length) {
case 0: case 0:
return null; return null;
@ -174,7 +175,7 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
return null; return null;
} }
int x; int x;
int y; int z;
switch (areas.length) { switch (areas.length) {
case 0: case 0:
PlotArea a = areas[0]; PlotArea a = areas[0];
@ -187,9 +188,9 @@ public class DefaultPlotAreaManager implements PlotAreaManager {
case 7: case 7:
case 8: case 8:
x = location.getX(); x = location.getX();
y = location.getY(); z = location.getZ();
for (PlotArea area : areas) { for (PlotArea area : areas) {
if (area.contains(x, y)) { if (area.contains(x, z)) {
return area; return area;
} }
} }

View File

@ -3,11 +3,33 @@ package com.github.intellectualsites.plotsquared.plot.object.worlds;
import com.github.intellectualsites.plotsquared.plot.object.Location; import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea; import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import org.jetbrains.annotations.NotNull;
public interface PlotAreaManager { public interface PlotAreaManager {
/**
* Get the plot area for a particular location. This
* method assumes that the caller already knows that
* the location belongs to a plot area, in which
* case it will return the appropriate plot area.
*
* If the location does not belong to a plot area,
* it may still return an area.
*
* @param location The location
* @return An applicable area, or null
*/
PlotArea getApplicablePlotArea(Location location); PlotArea getApplicablePlotArea(Location location);
PlotArea getPlotArea(Location location); /**
* Get the plot area, if there is any, for the given
* location. This may return null, if given location
* does not belong to a plot area.
*
* @param location The location
* @return The area, if found
*/
PlotArea getPlotArea(@NotNull Location location);
PlotArea getPlotArea(String world, String id); PlotArea getPlotArea(String world, String id);

View File

@ -5,6 +5,7 @@ import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.util.ArrayUtil; import com.github.intellectualsites.plotsquared.plot.util.ArrayUtil;
import com.github.intellectualsites.plotsquared.plot.util.SetupUtils; import com.github.intellectualsites.plotsquared.plot.util.SetupUtils;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import org.jetbrains.annotations.NotNull;
public class SinglePlotAreaManager extends DefaultPlotAreaManager { public class SinglePlotAreaManager extends DefaultPlotAreaManager {
private final SinglePlotArea[] array; private final SinglePlotArea[] array;
@ -82,7 +83,7 @@ public class SinglePlotAreaManager extends DefaultPlotAreaManager {
return isWorld(world) || world.equals("*") ? area : super.getPlotArea(world, id); return isWorld(world) || world.equals("*") ? area : super.getPlotArea(world, id);
} }
@Override public PlotArea getPlotArea(Location location) { @Override public PlotArea getPlotArea(@NotNull Location location) {
PlotArea found = super.getPlotArea(location); PlotArea found = super.getPlotArea(location);
if (found != null) { if (found != null) {
return found; return found;

View File

@ -52,7 +52,9 @@ public abstract class ChunkManager {
} }
queue.flush(); queue.flush();
} else { } else {
forceChunks.put(loc, force); if (force != null) {
forceChunks.put(loc, force);
}
addChunks.put(loc, add); addChunks.put(loc, add);
queue.regenChunk(loc.getX(), loc.getZ()); queue.regenChunk(loc.getX(), loc.getZ());
forceChunks.remove(loc); forceChunks.remove(loc);

View File

@ -3,6 +3,7 @@ package com.github.intellectualsites.plotsquared.plot.util.world;
import com.github.intellectualsites.plotsquared.commands.Command; import com.github.intellectualsites.plotsquared.commands.Command;
import com.github.intellectualsites.plotsquared.plot.config.Captions; import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.google.common.base.Preconditions;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
@ -18,7 +19,9 @@ import com.sk89q.worldedit.world.block.BlockType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class PatternUtil { public class PatternUtil {
public static BaseBlock apply(@NotNull Pattern pattern, int x, int y, int z) { public static BaseBlock apply(@NotNull Pattern pattern, int x, int y, int z) {
Preconditions.checkNotNull(pattern, "Pattern may not be null");
if (pattern instanceof BlockPattern if (pattern instanceof BlockPattern
|| pattern instanceof RandomPattern || pattern instanceof RandomPattern
|| pattern instanceof BlockState || pattern instanceof BlockState

View File

@ -14,6 +14,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class AbstractDBTest implements AbstractDB { public class AbstractDBTest implements AbstractDB {
@ -91,7 +92,8 @@ public class AbstractDBTest implements AbstractDB {
@Override public void setMerged(Plot plot, boolean[] merged) { @Override public void setMerged(Plot plot, boolean[] merged) {
} }
@Override public void swapPlots(Plot plot1, Plot plot2) { @Override public CompletableFuture<Boolean> swapPlots(Plot plot1, Plot plot2) {
return CompletableFuture.completedFuture(true);
} }
@Override public void setFlag(Plot plot, PlotFlag<?, ?> flag) { @Override public void setFlag(Plot plot, PlotFlag<?, ?> flag) {