mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-11-04 03:03:43 +01:00 
			
		
		
		
	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:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							30b83faab6
						
					
				
				
					commit
					05626c2c8f
				
			
							
								
								
									
										2
									
								
								.github/workflows/gradle.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/gradle.yml
									
									
									
									
										vendored
									
									
								
							@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,7 +486,8 @@ import java.util.regex.Pattern;
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (Settings.Redstone.DISABLE_OFFLINE) {
 | 
					        if (Settings.Redstone.DISABLE_OFFLINE) {
 | 
				
			||||||
            boolean disable;
 | 
					            boolean disable = false;
 | 
				
			||||||
 | 
					            if (!plot.getOwner().equals(DBFunc.SERVER)) {
 | 
				
			||||||
                if (plot.isMerged()) {
 | 
					                if (plot.isMerged()) {
 | 
				
			||||||
                    disable = true;
 | 
					                    disable = true;
 | 
				
			||||||
                    for (UUID owner : plot.getOwners()) {
 | 
					                    for (UUID owner : plot.getOwners()) {
 | 
				
			||||||
@@ -497,6 +499,7 @@ import java.util.regex.Pattern;
 | 
				
			|||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    disable = UUIDHandler.getPlayer(plot.guessOwner()) == null;
 | 
					                    disable = UUIDHandler.getPlayer(plot.guessOwner()) == null;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (disable) {
 | 
					            if (disable) {
 | 
				
			||||||
                for (UUID trusted : plot.getTrusted()) {
 | 
					                for (UUID trusted : plot.getTrusted()) {
 | 
				
			||||||
                    if (UUIDHandler.getPlayer(trusted) != null) {
 | 
					                    if (UUIDHandler.getPlayer(trusted) != null) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,8 +434,17 @@ 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++) {
 | 
				
			||||||
 | 
					                    try {
 | 
				
			||||||
 | 
					                        if (biomeSetter != null) {
 | 
				
			||||||
 | 
					                            biomeSetter.invoke(world, x, z, biome);
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
                            world.setBiome(x, y, z, biome);
 | 
					                            world.setBiome(x, y, z, biome);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                    } catch (final Exception e) {
 | 
				
			||||||
 | 
					                        PlotSquared.log("An error occurred setting the biome:");
 | 
				
			||||||
 | 
					                        e.printStackTrace();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
					                            try {
 | 
				
			||||||
                                result.set(origin.move(possible, () -> {
 | 
					                                result.set(origin.move(possible, () -> {
 | 
				
			||||||
                                    if (result.get()) {
 | 
					                                    if (result.get()) {
 | 
				
			||||||
                                        MainUtil.sendMessage(player,
 | 
					                                        MainUtil.sendMessage(player,
 | 
				
			||||||
                                            "Moving: " + origin + " -> " + possible);
 | 
					                                            "Moving: " + origin + " -> " + possible);
 | 
				
			||||||
                                        TaskManager.runTaskLater(task, 1);
 | 
					                                        TaskManager.runTaskLater(task, 1);
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
                            }, false));
 | 
					                                }, false).get());
 | 
				
			||||||
 | 
					                            } catch (InterruptedException | ExecutionException e) {
 | 
				
			||||||
 | 
					                                e.printStackTrace();
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                            if (result.get()) {
 | 
					                            if (result.get()) {
 | 
				
			||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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()) {
 | 
				
			||||||
 | 
					            Captions.MOVE_MERGED.send(player);
 | 
				
			||||||
 | 
					            return CompletableFuture.completedFuture(false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return plot1.move(plot2, () -> {}, false)
 | 
				
			||||||
 | 
					            .thenApply(result -> {
 | 
				
			||||||
 | 
					                if (result) {
 | 
				
			||||||
 | 
					                    MainUtil.sendMessage(player, Captions.MOVE_SUCCESS);
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    MainUtil.sendMessage(player, Captions.REQUIRES_UNOWNED);
 | 
					                    MainUtil.sendMessage(player, Captions.REQUIRES_UNOWNED);
 | 
				
			||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override public boolean onCommand(final PlotPlayer player, String[] args) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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(() -> {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
					            return CompletableFuture.completedFuture(false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return plot1.move(plot2, () -> {}, true)
 | 
				
			||||||
 | 
					            .thenApply(result -> {
 | 
				
			||||||
 | 
					                if (result) {
 | 
				
			||||||
                    MainUtil.sendMessage(player, Captions.SWAP_SUCCESS);
 | 
					                    MainUtil.sendMessage(player, Captions.SWAP_SUCCESS);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }, true)) {
 | 
					 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    MainUtil.sendMessage(player, Captions.SWAP_OVERLAP);
 | 
					                    MainUtil.sendMessage(player, Captions.SWAP_OVERLAP);
 | 
				
			||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override public boolean onCommand(final PlotPlayer player, String[] args) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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"),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 CompletableFuture<Boolean> future = new CompletableFuture<>();
 | 
				
			||||||
 | 
					        TaskManager.runTaskAsync(() -> {
 | 
				
			||||||
            final int id1 = getId(plot1);
 | 
					            final int id1 = getId(plot1);
 | 
				
			||||||
            final int id2 = getId(plot2);
 | 
					            final int id2 = getId(plot2);
 | 
				
			||||||
            final PlotId pos1 = plot1.getId();
 | 
					            final PlotId pos1 = plot1.getId();
 | 
				
			||||||
            final PlotId pos2 = plot2.getId();
 | 
					            final PlotId pos2 = plot2.getId();
 | 
				
			||||||
        addPlotTask(plot1, new UniqueStatement("swapPlots") {
 | 
					            try (final PreparedStatement preparedStatement = this.connection.prepareStatement("UPDATE `" + SQLManager.this.prefix
 | 
				
			||||||
            @Override public void set(PreparedStatement statement) throws SQLException {
 | 
					                + "plot` SET `plot_id_x` = ?, `plot_id_z` = ? WHERE `id` = ?")) {
 | 
				
			||||||
                statement.setInt(1, pos2.x);
 | 
					                preparedStatement.setInt(1, pos1.getX());
 | 
				
			||||||
                statement.setInt(2, pos2.y);
 | 
					                preparedStatement.setInt(2, pos1.getY());
 | 
				
			||||||
                statement.setInt(3, id1);
 | 
					                preparedStatement.setInt(3, id1);
 | 
				
			||||||
            }
 | 
					                preparedStatement.execute();
 | 
				
			||||||
 | 
					                preparedStatement.setInt(1, pos2.getX());
 | 
				
			||||||
            @Override public PreparedStatement get() throws SQLException {
 | 
					                preparedStatement.setInt(2, pos2.getY());
 | 
				
			||||||
                return SQLManager.this.connection.prepareStatement(
 | 
					                preparedStatement.setInt(3, id2);
 | 
				
			||||||
                    "UPDATE `" + SQLManager.this.prefix
 | 
					                preparedStatement.execute();
 | 
				
			||||||
                        + "plot` SET `plot_id_x` = ?, `plot_id_z` = ? WHERE `id` = ?");
 | 
					            } catch (final Exception e) {
 | 
				
			||||||
            }
 | 
					                PlotSquared.log(Captions.PREFIX.getTranslated() + "Failed to persist swap of " + plot1 + " and " + plot2 + "!");
 | 
				
			||||||
        });
 | 
					                e.printStackTrace();
 | 
				
			||||||
        addPlotTask(plot2, new UniqueStatement("swapPlots") {
 | 
					                future.complete(false);
 | 
				
			||||||
            @Override public void set(PreparedStatement statement) throws SQLException {
 | 
					                return;
 | 
				
			||||||
                statement.setInt(1, pos1.x);
 | 
					 | 
				
			||||||
                statement.setInt(2, pos1.y);
 | 
					 | 
				
			||||||
                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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 || plot.getOwner() == null) {
 | 
				
			||||||
        }
 | 
					            this.moveData(plot, null);
 | 
				
			||||||
        if (plot == null) {
 | 
					            return CompletableFuture.completedFuture(true);
 | 
				
			||||||
            this.moveData(plot, whenDone);
 | 
					 | 
				
			||||||
            return 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,18 +3091,40 @@ 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;
 | 
				
			||||||
 | 
					        if (plotIterator.hasNext()) {
 | 
				
			||||||
 | 
					            while (plotIterator.hasNext()) {
 | 
				
			||||||
 | 
					                final Plot plot = plotIterator.next();
 | 
				
			||||||
 | 
					                final Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y);
 | 
				
			||||||
 | 
					                final CompletableFuture<Boolean> swapResult = plot.swapData(other);
 | 
				
			||||||
 | 
					                if (future == null) {
 | 
				
			||||||
 | 
					                    future = swapResult;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    future = future.thenCombine(swapResult, (fn, th) -> fn);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            future = CompletableFuture.completedFuture(true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return future.thenApply(result -> {
 | 
				
			||||||
 | 
					            if (!result) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // copy terrain
 | 
					            // copy terrain
 | 
				
			||||||
        if (occupied) {
 | 
					            if (occupied.get()) {
 | 
				
			||||||
            Runnable swap = new Runnable() {
 | 
					                new Runnable() {
 | 
				
			||||||
                    @Override public void run() {
 | 
					                    @Override public void run() {
 | 
				
			||||||
                        if (regions.isEmpty()) {
 | 
					                        if (regions.isEmpty()) {
 | 
				
			||||||
 | 
					                            // Update signs
 | 
				
			||||||
 | 
					                            destination.setSign();
 | 
				
			||||||
 | 
					                            Plot.this.setSign();
 | 
				
			||||||
 | 
					                            // Run final tasks
 | 
				
			||||||
                            TaskManager.runTask(whenDone);
 | 
					                            TaskManager.runTask(whenDone);
 | 
				
			||||||
                        return;
 | 
					                        } else {
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                            CuboidRegion region = regions.poll();
 | 
					                            CuboidRegion region = regions.poll();
 | 
				
			||||||
                            Location[] corners = MainUtil.getCorners(getWorldName(), region);
 | 
					                            Location[] corners = MainUtil.getCorners(getWorldName(), region);
 | 
				
			||||||
                            Location pos1 = corners[0];
 | 
					                            Location pos1 = corners[0];
 | 
				
			||||||
@@ -3119,21 +3135,26 @@ public class Plot {
 | 
				
			|||||||
                            pos4.setWorld(destination.getWorldName());
 | 
					                            pos4.setWorld(destination.getWorldName());
 | 
				
			||||||
                            ChunkManager.manager.swap(pos1, pos2, pos3, pos4, this);
 | 
					                            ChunkManager.manager.swap(pos1, pos2, pos3, pos4, this);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
            };
 | 
					                    }
 | 
				
			||||||
            swap.run();
 | 
					                }.run();
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
            Runnable move = new Runnable() {
 | 
					                new Runnable() {
 | 
				
			||||||
                    @Override public void run() {
 | 
					                    @Override public void run() {
 | 
				
			||||||
                        if (regions.isEmpty()) {
 | 
					                        if (regions.isEmpty()) {
 | 
				
			||||||
                            Plot plot = destination.getRelative(0, 0);
 | 
					                            Plot plot = destination.getRelative(0, 0);
 | 
				
			||||||
                        for (Plot current : plot.getConnectedPlots()) {
 | 
					                            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);
 | 
					                                    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();
 | 
					                                plot.setSign();
 | 
				
			||||||
                                TaskManager.runTask(whenDone);
 | 
					                                TaskManager.runTask(whenDone);
 | 
				
			||||||
 | 
					                            };
 | 
				
			||||||
 | 
					                            if (originPlot != null) {
 | 
				
			||||||
 | 
					                                originPlot.clear(false, true, clearDone);
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                clearDone.run();
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                            return;
 | 
					                            return;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        final Runnable task = this;
 | 
					                        final Runnable task = this;
 | 
				
			||||||
@@ -3143,13 +3164,12 @@ public class Plot {
 | 
				
			|||||||
                        final Location pos2 = corners[1];
 | 
					                        final Location pos2 = corners[1];
 | 
				
			||||||
                        Location newPos = pos1.clone().add(offsetX, 0, offsetZ);
 | 
					                        Location newPos = pos1.clone().add(offsetX, 0, offsetZ);
 | 
				
			||||||
                        newPos.setWorld(destination.getWorldName());
 | 
					                        newPos.setWorld(destination.getWorldName());
 | 
				
			||||||
                    ChunkManager.manager.copyRegion(pos1, pos2, newPos,
 | 
					                        ChunkManager.manager.copyRegion(pos1, pos2, newPos, task);
 | 
				
			||||||
                        () -> ChunkManager.manager.regenerateRegion(pos1, pos2, false, task));
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
            };
 | 
					                }.run();
 | 
				
			||||||
            move.run();
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,9 @@ public abstract class ChunkManager {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            queue.flush();
 | 
					            queue.flush();
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (force != null) {
 | 
				
			||||||
                forceChunks.put(loc, force);
 | 
					                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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user