mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-31 01:23:44 +01:00 
			
		
		
		
	Add automatic backups and implement them /plot clear and /plot set <component>.
				
					
				
			This commit is contained in:
		| @@ -25,14 +25,30 @@ | ||||
|  */ | ||||
| package com.plotsquared.core.backup; | ||||
|  | ||||
| import com.plotsquared.core.PlotSquared; | ||||
| import com.plotsquared.core.player.PlotPlayer; | ||||
| import com.plotsquared.core.plot.Plot; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
|  | ||||
| import java.nio.file.Path; | ||||
| import java.util.concurrent.CompletableFuture; | ||||
| import java.util.Objects; | ||||
|  | ||||
| public interface BackupManager { | ||||
|  | ||||
|     /** | ||||
|      * This will perform an automatic backup of the plot iff the plot has an owner, | ||||
|      * automatic backups are enabled and the plot is not merged. | ||||
|      * Otherwise it will complete immediately. | ||||
|      * | ||||
|      * @param player   Player that triggered the backup | ||||
|      * @param plot     Plot to perform the automatic backup on | ||||
|      * @param whenDone Action that runs when the automatic backup has been completed | ||||
|      */ | ||||
|     static void backup(@Nullable PlotPlayer player, @NotNull final Plot plot, @NotNull Runnable whenDone) { | ||||
|         Objects.requireNonNull(PlotSquared.imp()).getBackupManager().automaticBackup(player, plot, whenDone); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the backup profile for a plot based on its | ||||
|      * current owner (if there is one) | ||||
| @@ -47,10 +63,11 @@ public interface BackupManager { | ||||
|      * automatic backups are enabled and the plot is not merged. | ||||
|      * Otherwise it will complete immediately. | ||||
|      * | ||||
|      * @param plot Plot to perform the automatic backup on | ||||
|      * @return Future that completes when the backup is finished | ||||
|      * @param player   Player that triggered the backup | ||||
|      * @param plot     Plot to perform the automatic backup on | ||||
|      * @param whenDone Action that runs when the automatic backup has been completed | ||||
|      */ | ||||
|     @NotNull CompletableFuture<?> automaticBackup(@NotNull final Plot plot); | ||||
|     void automaticBackup(@Nullable PlotPlayer player, @NotNull final Plot plot, @NotNull Runnable whenDone); | ||||
|  | ||||
|     /** | ||||
|      * Get the directory in which backups are stored | ||||
|   | ||||
| @@ -26,12 +26,13 @@ | ||||
| package com.plotsquared.core.backup; | ||||
|  | ||||
| import com.plotsquared.core.PlotSquared; | ||||
| import com.plotsquared.core.player.PlotPlayer; | ||||
| import com.plotsquared.core.plot.Plot; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
|  | ||||
| import java.nio.file.Path; | ||||
| import java.util.Objects; | ||||
| import java.util.concurrent.CompletableFuture; | ||||
|  | ||||
| /** | ||||
|  * {@inheritDoc} | ||||
| @@ -42,8 +43,9 @@ public class NullBackupManager implements BackupManager { | ||||
|         return new NullBackupProfile(); | ||||
|     } | ||||
|  | ||||
|     @Override @NotNull public CompletableFuture<?> automaticBackup(@NotNull Plot plot) { | ||||
|         return CompletableFuture.completedFuture(null); | ||||
|     @Override public void automaticBackup(@Nullable PlotPlayer plotPlayer, | ||||
|         @NotNull Plot plot, @NotNull Runnable whenDone) { | ||||
|         whenDone.run(); | ||||
|     } | ||||
|  | ||||
|     @Override @NotNull public Path getBackupPath() { | ||||
|   | ||||
| @@ -40,6 +40,7 @@ import java.nio.file.Path; | ||||
| import java.nio.file.attribute.BasicFileAttributes; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
| import java.util.UUID; | ||||
| @@ -95,6 +96,7 @@ public class PlayerBackupProfile implements BackupProfile { | ||||
|                 } catch (IOException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|                 backups.sort(Comparator.comparingLong(Backup::getCreationTime).reversed()); | ||||
|                 return (this.backupCache = backups); | ||||
|             }); | ||||
|         } | ||||
|   | ||||
| @@ -28,17 +28,20 @@ package com.plotsquared.core.backup; | ||||
| import com.google.common.cache.Cache; | ||||
| import com.google.common.cache.CacheBuilder; | ||||
| import com.plotsquared.core.PlotSquared; | ||||
| import com.plotsquared.core.configuration.Captions; | ||||
| import com.plotsquared.core.configuration.Settings; | ||||
| import com.plotsquared.core.player.PlotPlayer; | ||||
| import com.plotsquared.core.plot.Plot; | ||||
| import com.plotsquared.core.util.task.TaskManager; | ||||
| import lombok.AccessLevel; | ||||
| import lombok.Getter; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import org.jetbrains.annotations.Nullable; | ||||
|  | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.Objects; | ||||
| import java.util.concurrent.CompletableFuture; | ||||
| import java.util.concurrent.ExecutionException; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| @@ -75,12 +78,28 @@ import java.util.concurrent.TimeUnit; | ||||
|         return new NullBackupProfile(); | ||||
|     } | ||||
|  | ||||
|     @Override @NotNull public CompletableFuture<?> automaticBackup(@NotNull final Plot plot) { | ||||
|     @Override public void automaticBackup(@Nullable PlotPlayer player, @NotNull final Plot plot, @NotNull Runnable whenDone) { | ||||
|         final BackupProfile profile; | ||||
|         if (!this.shouldAutomaticallyBackup() || (profile = getProfile(plot)) instanceof NullBackupProfile) { | ||||
|             return CompletableFuture.completedFuture(null); | ||||
|             whenDone.run(); | ||||
|         } else { | ||||
|             if (player != null) { | ||||
|                 Captions.BACKUP_AUTOMATIC_STARTED.send(player); | ||||
|             } | ||||
|             profile.createBackup().whenComplete((backup, throwable) -> { | ||||
|                if (throwable != null) { | ||||
|                    if (player != null) { | ||||
|                        Captions.BACKUP_AUTOMATIC_FAILURE.send(player, throwable.getMessage()); | ||||
|                    } | ||||
|                    throwable.printStackTrace(); | ||||
|                } else { | ||||
|                    if (player != null) { | ||||
|                        Captions.BACKUP_AUTOMATIC_FINISHED.send(player); | ||||
|                        TaskManager.runTaskAsync(whenDone); | ||||
|                    } | ||||
|                } | ||||
|             }); | ||||
|         } | ||||
|         return profile.createBackup(); | ||||
|     } | ||||
|  | ||||
|     @Override public boolean shouldAutomaticallyBackup() { | ||||
|   | ||||
| @@ -26,6 +26,7 @@ | ||||
| package com.plotsquared.core.command; | ||||
|  | ||||
| import com.plotsquared.core.PlotSquared; | ||||
| import com.plotsquared.core.backup.BackupManager; | ||||
| import com.plotsquared.core.configuration.Captions; | ||||
| import com.plotsquared.core.configuration.Settings; | ||||
| import com.plotsquared.core.events.PlotFlagRemoveEvent; | ||||
| @@ -82,38 +83,40 @@ public class Clear extends Command { | ||||
|         checkTrue(force || !Settings.Done.RESTRICT_BUILDING || !DoneFlag.isDone(plot) || Permissions | ||||
|             .hasPermission(player, Captions.PERMISSION_CONTINUE), Captions.DONE_ALREADY_DONE); | ||||
|         confirm.run(this, () -> { | ||||
|             final long start = System.currentTimeMillis(); | ||||
|             boolean result = plot.clear(true, false, () -> { | ||||
|                 plot.unlink(); | ||||
|                 GlobalBlockQueue.IMP.addEmptyTask(() -> { | ||||
|                     plot.removeRunning(); | ||||
|                     // If the state changes, then mark it as no longer done | ||||
|                     if (DoneFlag.isDone(plot)) { | ||||
|                         PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(DoneFlag.class); | ||||
|                         PlotFlagRemoveEvent event = | ||||
|                             PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot); | ||||
|                         if (event.getEventResult() != Result.DENY) { | ||||
|                             plot.removeFlag(event.getFlag()); | ||||
|             BackupManager.backup(player, plot, () -> { | ||||
|                 final long start = System.currentTimeMillis(); | ||||
|                 boolean result = plot.clear(true, false, () -> { | ||||
|                     plot.unlink(); | ||||
|                     GlobalBlockQueue.IMP.addEmptyTask(() -> { | ||||
|                         plot.removeRunning(); | ||||
|                         // If the state changes, then mark it as no longer done | ||||
|                         if (DoneFlag.isDone(plot)) { | ||||
|                             PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(DoneFlag.class); | ||||
|                             PlotFlagRemoveEvent event = | ||||
|                                 PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot); | ||||
|                             if (event.getEventResult() != Result.DENY) { | ||||
|                                 plot.removeFlag(event.getFlag()); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     if (!plot.getFlag(AnalysisFlag.class).isEmpty()) { | ||||
|                         PlotFlag<?, ?> plotFlag = | ||||
|                             plot.getFlagContainer().getFlag(AnalysisFlag.class); | ||||
|                         PlotFlagRemoveEvent event = | ||||
|                             PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot); | ||||
|                         if (event.getEventResult() != Result.DENY) { | ||||
|                             plot.removeFlag(event.getFlag()); | ||||
|                         if (!plot.getFlag(AnalysisFlag.class).isEmpty()) { | ||||
|                             PlotFlag<?, ?> plotFlag = | ||||
|                                 plot.getFlagContainer().getFlag(AnalysisFlag.class); | ||||
|                             PlotFlagRemoveEvent event = | ||||
|                                 PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot); | ||||
|                             if (event.getEventResult() != Result.DENY) { | ||||
|                                 plot.removeFlag(event.getFlag()); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     MainUtil.sendMessage(player, Captions.CLEARING_DONE, | ||||
|                         "" + (System.currentTimeMillis() - start)); | ||||
|                         MainUtil.sendMessage(player, Captions.CLEARING_DONE, | ||||
|                             "" + (System.currentTimeMillis() - start)); | ||||
|                     }); | ||||
|                 }); | ||||
|                 if (!result) { | ||||
|                     MainUtil.sendMessage(player, Captions.WAIT_FOR_TIMER); | ||||
|                 } else { | ||||
|                     plot.addRunning(); | ||||
|                 } | ||||
|             }); | ||||
|             if (!result) { | ||||
|                 MainUtil.sendMessage(player, Captions.WAIT_FOR_TIMER); | ||||
|             } else { | ||||
|                 plot.addRunning(); | ||||
|             } | ||||
|         }, null); | ||||
|         return CompletableFuture.completedFuture(true); | ||||
|     } | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
|  */ | ||||
| package com.plotsquared.core.command; | ||||
|  | ||||
| import com.plotsquared.core.backup.BackupManager; | ||||
| import com.plotsquared.core.configuration.CaptionUtility; | ||||
| import com.plotsquared.core.configuration.Captions; | ||||
| import com.plotsquared.core.player.PlotPlayer; | ||||
| @@ -91,12 +92,15 @@ public class Set extends SubCommand { | ||||
|                             MainUtil.sendMessage(player, Captions.WAIT_FOR_TIMER); | ||||
|                             return false; | ||||
|                         } | ||||
|                         plot.addRunning(); | ||||
|                         for (Plot current : plot.getConnectedPlots()) { | ||||
|                             current.setComponent(component, pattern); | ||||
|                         } | ||||
|                         MainUtil.sendMessage(player, Captions.GENERATING_COMPONENT); | ||||
|                         GlobalBlockQueue.IMP.addEmptyTask(plot::removeRunning); | ||||
|  | ||||
|                         BackupManager.backup(player, plot, () -> { | ||||
|                             plot.addRunning(); | ||||
|                             for (Plot current : plot.getConnectedPlots()) { | ||||
|                                 current.setComponent(component, pattern); | ||||
|                             } | ||||
|                             MainUtil.sendMessage(player, Captions.GENERATING_COMPONENT); | ||||
|                             GlobalBlockQueue.IMP.addEmptyTask(plot::removeRunning); | ||||
|                         }); | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|   | ||||
| @@ -759,6 +759,9 @@ public enum Captions implements Caption { | ||||
|     BACKUP_LIST_HEADER("$1Available backups for plot $2%s", "Backups"), | ||||
|     BACKUP_LIST_ENTRY("$3- $1#%s0 $2%s1", "Backups"), | ||||
|     BACKUP_LIST_FAILED("$2Backup listing failed: %s", "Backups"), | ||||
|     BACKUP_AUTOMATIC_STARTED("$1Backing up the plot...", "Backups"), | ||||
|     BACKUP_AUTOMATIC_FINISHED("$1The automatic backup process finished successfully!", "Backups"), | ||||
|     BACKUP_AUTOMATIC_FAILURE("$2The automatic backup process failed. Your pending action has been canceled. Reason: %s", "Backups"), | ||||
|     //</editor-fold> | ||||
|  | ||||
|     //<editor-fold desc="Generic"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Alexander Söderberg
					Alexander Söderberg