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; package com.plotsquared.core.backup;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.concurrent.CompletableFuture; import java.util.Objects;
public interface BackupManager { 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 * Get the backup profile for a plot based on its
* current owner (if there is one) * current owner (if there is one)
@ -47,10 +63,11 @@ public interface BackupManager {
* automatic backups are enabled and the plot is not merged. * automatic backups are enabled and the plot is not merged.
* Otherwise it will complete immediately. * Otherwise it will complete immediately.
* *
* @param plot Plot to perform the automatic backup on * @param player Player that triggered the backup
* @return Future that completes when the backup is finished * @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 * Get the directory in which backups are stored

View File

@ -26,12 +26,13 @@
package com.plotsquared.core.backup; package com.plotsquared.core.backup;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.CompletableFuture;
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -42,8 +43,9 @@ public class NullBackupManager implements BackupManager {
return new NullBackupProfile(); return new NullBackupProfile();
} }
@Override @NotNull public CompletableFuture<?> automaticBackup(@NotNull Plot plot) { @Override public void automaticBackup(@Nullable PlotPlayer plotPlayer,
return CompletableFuture.completedFuture(null); @NotNull Plot plot, @NotNull Runnable whenDone) {
whenDone.run();
} }
@Override @NotNull public Path getBackupPath() { @Override @NotNull public Path getBackupPath() {

View File

@ -40,6 +40,7 @@ import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@ -95,6 +96,7 @@ public class PlayerBackupProfile implements BackupProfile {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
backups.sort(Comparator.comparingLong(Backup::getCreationTime).reversed());
return (this.backupCache = backups); 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.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.task.TaskManager;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -75,12 +78,28 @@ import java.util.concurrent.TimeUnit;
return new NullBackupProfile(); 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; final BackupProfile profile;
if (!this.shouldAutomaticallyBackup() || (profile = getProfile(plot)) instanceof NullBackupProfile) { 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() { @Override public boolean shouldAutomaticallyBackup() {

View File

@ -26,6 +26,7 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.backup.BackupManager;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.events.PlotFlagRemoveEvent; 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 checkTrue(force || !Settings.Done.RESTRICT_BUILDING || !DoneFlag.isDone(plot) || Permissions
.hasPermission(player, Captions.PERMISSION_CONTINUE), Captions.DONE_ALREADY_DONE); .hasPermission(player, Captions.PERMISSION_CONTINUE), Captions.DONE_ALREADY_DONE);
confirm.run(this, () -> { confirm.run(this, () -> {
final long start = System.currentTimeMillis(); BackupManager.backup(player, plot, () -> {
boolean result = plot.clear(true, false, () -> { final long start = System.currentTimeMillis();
plot.unlink(); boolean result = plot.clear(true, false, () -> {
GlobalBlockQueue.IMP.addEmptyTask(() -> { plot.unlink();
plot.removeRunning(); GlobalBlockQueue.IMP.addEmptyTask(() -> {
// If the state changes, then mark it as no longer done plot.removeRunning();
if (DoneFlag.isDone(plot)) { // If the state changes, then mark it as no longer done
PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(DoneFlag.class); if (DoneFlag.isDone(plot)) {
PlotFlagRemoveEvent event = PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(DoneFlag.class);
PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot); PlotFlagRemoveEvent event =
if (event.getEventResult() != Result.DENY) { PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot);
plot.removeFlag(event.getFlag()); if (event.getEventResult() != Result.DENY) {
plot.removeFlag(event.getFlag());
}
} }
} if (!plot.getFlag(AnalysisFlag.class).isEmpty()) {
if (!plot.getFlag(AnalysisFlag.class).isEmpty()) { PlotFlag<?, ?> plotFlag =
PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(AnalysisFlag.class);
plot.getFlagContainer().getFlag(AnalysisFlag.class); PlotFlagRemoveEvent event =
PlotFlagRemoveEvent event = PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot);
PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot); if (event.getEventResult() != Result.DENY) {
if (event.getEventResult() != Result.DENY) { plot.removeFlag(event.getFlag());
plot.removeFlag(event.getFlag()); }
} }
} MainUtil.sendMessage(player, Captions.CLEARING_DONE,
MainUtil.sendMessage(player, Captions.CLEARING_DONE, "" + (System.currentTimeMillis() - start));
"" + (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); }, null);
return CompletableFuture.completedFuture(true); return CompletableFuture.completedFuture(true);
} }

View File

@ -25,6 +25,7 @@
*/ */
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.backup.BackupManager;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
@ -91,12 +92,15 @@ public class Set extends SubCommand {
MainUtil.sendMessage(player, Captions.WAIT_FOR_TIMER); MainUtil.sendMessage(player, Captions.WAIT_FOR_TIMER);
return false; return false;
} }
plot.addRunning();
for (Plot current : plot.getConnectedPlots()) { BackupManager.backup(player, plot, () -> {
current.setComponent(component, pattern); plot.addRunning();
} for (Plot current : plot.getConnectedPlots()) {
MainUtil.sendMessage(player, Captions.GENERATING_COMPONENT); current.setComponent(component, pattern);
GlobalBlockQueue.IMP.addEmptyTask(plot::removeRunning); }
MainUtil.sendMessage(player, Captions.GENERATING_COMPONENT);
GlobalBlockQueue.IMP.addEmptyTask(plot::removeRunning);
});
return true; 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_HEADER("$1Available backups for plot $2%s", "Backups"),
BACKUP_LIST_ENTRY("$3- $1#%s0 $2%s1", "Backups"), BACKUP_LIST_ENTRY("$3- $1#%s0 $2%s1", "Backups"),
BACKUP_LIST_FAILED("$2Backup listing failed: %s", "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>
//<editor-fold desc="Generic"> //<editor-fold desc="Generic">