diff --git a/Core/src/main/java/com/plotsquared/core/command/Backup.java b/Core/src/main/java/com/plotsquared/core/command/Backup.java
new file mode 100644
index 000000000..8e16758bb
--- /dev/null
+++ b/Core/src/main/java/com/plotsquared/core/command/Backup.java
@@ -0,0 +1,136 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * PlotSquared plot management system for Minecraft
+ * Copyright (C) 2020 IntellectualSites
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.plotsquared.core.command;
+
+import com.plotsquared.core.PlotSquared;
+import com.plotsquared.core.backup.BackupProfile;
+import com.plotsquared.core.backup.PlayerBackupProfile;
+import com.plotsquared.core.configuration.Captions;
+import com.plotsquared.core.player.PlotPlayer;
+import com.plotsquared.core.plot.Plot;
+import com.plotsquared.core.util.task.RunnableVal2;
+import com.plotsquared.core.util.task.RunnableVal3;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+@CommandDeclaration(command = "backup",
+usage = "/plot backup ",
+description = "Manage plot backups",
+category = CommandCategory.SETTINGS,
+requiredType = RequiredType.PLAYER,
+permission = "plots.backup")
+public final class Backup extends Command {
+
+ public Backup() {
+ super(MainCommand.getInstance(), true);
+ }
+
+ private static boolean sendMessage(PlotPlayer player, Captions message, Object... args) {
+ message.send(player, args);
+ return true;
+ }
+
+ @Override public CompletableFuture execute(PlotPlayer player, String[] args,
+ RunnableVal3 confirm,
+ RunnableVal2 whenDone) throws CommandException {
+ if (args.length == 0 || !Arrays.asList("save", "list", "load")
+ .contains(args[0].toLowerCase(Locale.ENGLISH))) {
+ return CompletableFuture.completedFuture(sendMessage(player, Captions.BACKUP_USAGE));
+ }
+ return super.execute(player, args, confirm, whenDone);
+ }
+
+ @Override public Collection tab(PlotPlayer player, String[] args, boolean space) {
+ if (args.length == 1) {
+ return Stream.of("save", "list", "save")
+ .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH)))
+ .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {})
+ .collect(Collectors.toList());
+ } else if (args[0].equalsIgnoreCase("load") && args.length == 2) {
+
+ final Plot plot = player.getCurrentPlot();
+ if (plot != null) {
+ final BackupProfile backupProfile = Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot);
+ if (!(backupProfile instanceof PlayerBackupProfile)) {
+ final CompletableFuture> backupList = backupProfile.listBackups();
+ if (backupList.isDone()) {
+ final List backups = backupList.getNow(new ArrayList<>());
+ if (backups.isEmpty()) {
+ return new ArrayList<>();
+ }
+ return IntStream.range(1, 1 + backups.size()).mapToObj(i -> new Command(null, false, Integer.toString(i),
+ "", RequiredType.NONE, null) {}).collect(Collectors.toList());
+
+ }
+ }
+ }
+ }
+ return tabOf(player, args, space);
+ }
+
+ @CommandDeclaration(command = "save",
+ usage = "/plot backup save",
+ description = "Create a plot backup",
+ category = CommandCategory.SETTINGS,
+ requiredType = RequiredType.PLAYER,
+ permission = "plots.backup.save")
+ public void save(final Command command, final PlotPlayer player, final String[] args,
+ final RunnableVal3 confirm,
+ final RunnableVal2 whenDone) {
+ }
+
+ @CommandDeclaration(command = "list",
+ usage = "/plot backup list",
+ description = "List available plot backups",
+ category = CommandCategory.SETTINGS,
+ requiredType = RequiredType.PLAYER,
+ permission = "plots.backup.list")
+ public void list(final Command command, final PlotPlayer player, final String[] args,
+ final RunnableVal3 confirm,
+ final RunnableVal2 whenDone) {
+ }
+
+ @CommandDeclaration(command = "load",
+ usage = "/plot backup load <#>",
+ description = "Restore a plot backup",
+ category = CommandCategory.SETTINGS,
+ requiredType = RequiredType.PLAYER,
+ permission = "plots.backup.load")
+ public void load(final Command command, final PlotPlayer player, final String[] args,
+ final RunnableVal3 confirm,
+ final RunnableVal2 whenDone) {
+ }
+
+}
diff --git a/Core/src/main/java/com/plotsquared/core/command/MainCommand.java b/Core/src/main/java/com/plotsquared/core/command/MainCommand.java
index fb1dc68ed..03be061ca 100644
--- a/Core/src/main/java/com/plotsquared/core/command/MainCommand.java
+++ b/Core/src/main/java/com/plotsquared/core/command/MainCommand.java
@@ -127,6 +127,7 @@ public class MainCommand extends Command {
new SetHome();
new Cluster();
new DebugImportWorlds();
+ new Backup();
if (Settings.Ratings.USE_LIKES) {
new Like();
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 bbba53f6f..d63019a21 100644
--- a/Core/src/main/java/com/plotsquared/core/configuration/Captions.java
+++ b/Core/src/main/java/com/plotsquared/core/configuration/Captions.java
@@ -757,6 +757,10 @@ public enum Captions implements Caption {
false, "Info"),
//
+ //
+ BACKUP_USAGE("$1Usage: $2/plot backup save/list/load", "Backups"),
+ //
+
/**
* Legacy Configuration Conversion
*/