mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-31 17:43:44 +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:
		 Alexander Söderberg
					Alexander Söderberg
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						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,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()) { | ||||||
|   | |||||||
| @@ -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(); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -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); | ||||||
|                             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; | ||||||
|                             } |                             } | ||||||
|   | |||||||
| @@ -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()) { | ||||||
|             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; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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); | ||||||
|                 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; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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 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) { | ||||||
|   | |||||||
| @@ -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) { |         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; | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -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 { | ||||||
|             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); | ||||||
|   | |||||||
| @@ -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