diff --git a/Core/src/main/java/com/plotsquared/core/backup/Backup.java b/Core/src/main/java/com/plotsquared/core/backup/Backup.java
new file mode 100644
index 000000000..3adb9acf0
--- /dev/null
+++ b/Core/src/main/java/com/plotsquared/core/backup/Backup.java
@@ -0,0 +1,43 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * 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.backup;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+
+import java.nio.file.Path;
+
+/**
+ * Object representing a plot backup. This does not actually contain the
+ * backup itself, it is just a pointer to an available backup
+ */
+@RequiredArgsConstructor(access = AccessLevel.PACKAGE) public class Backup {
+
+ private final BackupProfile owner;
+ private final long creationTime;
+ private final Path file;
+
+}
diff --git a/Core/src/main/java/com/plotsquared/core/backup/BackupManager.java b/Core/src/main/java/com/plotsquared/core/backup/BackupManager.java
new file mode 100644
index 000000000..16f30eeb8
--- /dev/null
+++ b/Core/src/main/java/com/plotsquared/core/backup/BackupManager.java
@@ -0,0 +1,61 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * 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.backup;
+
+import com.plotsquared.core.PlotSquared;
+import com.plotsquared.core.plot.Plot;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class BackupManager {
+
+ @Getter private final Path backupPath;
+
+ public BackupManager() throws Exception {
+ this.backupPath = PlotSquared.imp().getDirectory().toPath().resolve("backups");
+ if (!Files.exists(backupPath)) {
+ Files.createDirectory(backupPath);
+ }
+ }
+
+ /**
+ * Get the backup profile for a plot based on its
+ * current owner (if there is one)
+ *
+ * @param plot Plot to get the backup profile for
+ * @return Backup profile
+ */
+ @NotNull public BackupProfile getProfile(@NotNull final Plot plot) {
+ if (plot.hasOwner()) {
+ return new PlayerBackupProfile(plot.getOwnerAbs(), plot, this);
+ }
+ return new NullBackupProfile();
+ }
+
+}
diff --git a/Core/src/main/java/com/plotsquared/core/backup/BackupProfile.java b/Core/src/main/java/com/plotsquared/core/backup/BackupProfile.java
new file mode 100644
index 000000000..8ba756e87
--- /dev/null
+++ b/Core/src/main/java/com/plotsquared/core/backup/BackupProfile.java
@@ -0,0 +1,57 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * 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.backup;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+public interface BackupProfile {
+
+ /**
+ * Asynchronously populate a list of available backups under this profile
+ *
+ * @return Future that will be completed with available backups
+ */
+ @NotNull CompletableFuture> listBackups();
+
+ /**
+ * Remove all backups stored for this profile
+ */
+ void destroy() throws IOException;
+
+ /**
+ * Get the directory containing the backups for this profile.
+ * This directory may not actually exist.
+ *
+ * @return Folder that contains the backups for this profile
+ */
+ @NotNull Path getBackupDirectory();
+
+}
diff --git a/Core/src/main/java/com/plotsquared/core/backup/NullBackupProfile.java b/Core/src/main/java/com/plotsquared/core/backup/NullBackupProfile.java
new file mode 100644
index 000000000..add8c3eb3
--- /dev/null
+++ b/Core/src/main/java/com/plotsquared/core/backup/NullBackupProfile.java
@@ -0,0 +1,52 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * 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.backup;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Backup profile for a plot without an owner
+ */
+public class NullBackupProfile implements BackupProfile {
+
+ @Override @NotNull public CompletableFuture> listBackups() {
+ return CompletableFuture.completedFuture(Collections.emptyList());
+ }
+
+ @Override public void destroy(){
+ }
+
+ @Override @NotNull public Path getBackupDirectory() {
+ return new File(".").toPath();
+ }
+
+}
diff --git a/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java b/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java
new file mode 100644
index 000000000..c87286093
--- /dev/null
+++ b/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java
@@ -0,0 +1,97 @@
+/*
+ * _____ _ _ _____ _
+ * | __ \| | | | / ____| | |
+ * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
+ * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
+ * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
+ * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
+ * | |
+ * |_|
+ * 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.backup;
+
+import com.plotsquared.core.plot.Plot;
+import lombok.RequiredArgsConstructor;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * A profile associated with a player (normally a plot owner) and a
+ * plot, which is used to store and retrieve plot backups
+ * {@inheritDoc}
+ */
+@RequiredArgsConstructor
+public class PlayerBackupProfile implements BackupProfile {
+
+ private final UUID owner;
+ private final Plot plot;
+ private final BackupManager backupManager;
+
+ private static boolean isValidFile(@NotNull final Path path) {
+ final String name = path.getFileName().toString();
+ return name.endsWith(".schem") || name.endsWith(".schematic");
+ }
+
+ @NotNull public CompletableFuture> listBackups() {
+ return CompletableFuture.supplyAsync(() -> {
+ final Path path = this.getBackupDirectory();
+ if (!Files.exists(path)) {
+ try {
+ Files.createDirectories(path);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return Collections.emptyList();
+ }
+ }
+ final List backups = new ArrayList<>();
+ try {
+ Files.walk(path).filter(PlayerBackupProfile::isValidFile).forEach(file -> {
+ try {
+ final BasicFileAttributes
+ basicFileAttributes = Files.readAttributes(file, BasicFileAttributes.class);
+ backups.add(new Backup(this, basicFileAttributes.creationTime().toMillis(), file));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return backups;
+ });
+ }
+
+ public void destroy() throws IOException {
+ Files.delete(this.getBackupDirectory());
+ }
+
+ @NotNull public Path getBackupDirectory() {
+ return backupManager.getBackupPath().resolve(plot.getArea().getId())
+ .resolve(plot.getId().toCommaSeparatedString()).resolve(owner.toString());
+ }
+
+}