Add automatic backups and implement them /plot clear and /plot set <component>.

This commit is contained in:
Alexander Söderberg 2020-05-10 20:31:07 +02:00
parent c4a70c0945
commit e0c9a802d8
No known key found for this signature in database
GPG Key ID: C0207FF7EA146678
7 changed files with 95 additions and 45 deletions

View File

@ -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

View File

@ -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() {

View File

@ -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);
});
}

View File

@ -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() {

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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">