diff --git a/Core/src/main/java/com/plotsquared/core/backup/BackupManager.java b/Core/src/main/java/com/plotsquared/core/backup/BackupManager.java index bfa4ad37f..4ba4a44f4 100644 --- a/Core/src/main/java/com/plotsquared/core/backup/BackupManager.java +++ b/Core/src/main/java/com/plotsquared/core/backup/BackupManager.java @@ -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 diff --git a/Core/src/main/java/com/plotsquared/core/backup/NullBackupManager.java b/Core/src/main/java/com/plotsquared/core/backup/NullBackupManager.java index d5f9bd954..2d8c04a76 100644 --- a/Core/src/main/java/com/plotsquared/core/backup/NullBackupManager.java +++ b/Core/src/main/java/com/plotsquared/core/backup/NullBackupManager.java @@ -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() { diff --git a/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java b/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java index 232602694..4bbc0a76b 100644 --- a/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java +++ b/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java @@ -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); }); } diff --git a/Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java b/Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java index 4c206b9ad..4f4a514bc 100644 --- a/Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java +++ b/Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java @@ -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() { diff --git a/Core/src/main/java/com/plotsquared/core/command/Clear.java b/Core/src/main/java/com/plotsquared/core/command/Clear.java index cc8ab64ab..2af1c4ed5 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Clear.java +++ b/Core/src/main/java/com/plotsquared/core/command/Clear.java @@ -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); } diff --git a/Core/src/main/java/com/plotsquared/core/command/Set.java b/Core/src/main/java/com/plotsquared/core/command/Set.java index ca301a2fa..700c0854a 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Set.java +++ b/Core/src/main/java/com/plotsquared/core/command/Set.java @@ -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; } } diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java index 5626d877b..509082221 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java @@ -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"), // //