forked from SteamWar/SteamWar
Implement rest of PlotRegionBackups
This commit is contained in:
@@ -25,12 +25,15 @@ import lombok.RequiredArgsConstructor;
|
|||||||
|
|
||||||
import javax.annotation.CheckReturnValue;
|
import javax.annotation.CheckReturnValue;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public interface RegionBackups {
|
public interface RegionBackups {
|
||||||
|
|
||||||
|
DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd' 'HH:mm:ss");
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
enum BackupType {
|
enum BackupType {
|
||||||
MANUAL(5),
|
MANUAL(5),
|
||||||
@@ -60,6 +63,10 @@ public interface RegionBackups {
|
|||||||
@CheckReturnValue
|
@CheckReturnValue
|
||||||
public abstract boolean load();
|
public abstract boolean load();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void save() {
|
||||||
|
}
|
||||||
|
|
||||||
public abstract long getCreationTime();
|
public abstract long getCreationTime();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,6 +74,10 @@ public interface RegionBackups {
|
|||||||
return Long.compare(getCreationTime(), o.getCreationTime());
|
return Long.compare(getCreationTime(), o.getCreationTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void load(RegionData regionData) {
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("java:S3038") // This forces everybody to implement 'deleteRegion' for Backups!
|
@SuppressWarnings("java:S3038") // This forces everybody to implement 'deleteRegion' for Backups!
|
||||||
@Override
|
@Override
|
||||||
public abstract void delete();
|
public abstract void delete();
|
||||||
|
|||||||
+3
-3
@@ -50,7 +50,7 @@ public class DynamicRegionCommand extends SWCommand {
|
|||||||
|
|
||||||
// Check location!
|
// Check location!
|
||||||
|
|
||||||
Class<? extends DynamicRegion> regionClass = DynamicRegionSystem.identifierDataMap.get(regionType);
|
Class<? extends DynamicRegion> regionClass = DynamicRegionSystem.getRegionClassByIdentifier(regionType);
|
||||||
DynamicRegion dynamicRegion = DynamicRegionRepository.constructRegion(regionClass, UUID.randomUUID(), tile.getMinX(), tile.getMinZ());
|
DynamicRegion dynamicRegion = DynamicRegionRepository.constructRegion(regionClass, UUID.randomUUID(), tile.getMinX(), tile.getMinZ());
|
||||||
if (dynamicRegion == null) {
|
if (dynamicRegion == null) {
|
||||||
// TODO: Give error to user
|
// TODO: Give error to user
|
||||||
@@ -73,7 +73,7 @@ public class DynamicRegionCommand extends SWCommand {
|
|||||||
return new TypeMapper<>() {
|
return new TypeMapper<>() {
|
||||||
@Override
|
@Override
|
||||||
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
if (DynamicRegionSystem.identifierDataMap.containsKey(s)) {
|
if (DynamicRegionSystem.hasRegionClassForIdentifier(s)) {
|
||||||
return s;
|
return s;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@@ -82,7 +82,7 @@ public class DynamicRegionCommand extends SWCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||||
return DynamicRegionSystem.identifierDataMap.keySet();
|
return DynamicRegionSystem.allRegionIdentifiers();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-2
@@ -62,8 +62,24 @@ public class DynamicRegionSystem implements RegionSystem {
|
|||||||
regionTypeMap.getOrDefault(region.getType(), Collections.emptySet()).remove(region);
|
regionTypeMap.getOrDefault(region.getType(), Collections.emptySet()).remove(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<Class<? extends DynamicRegion>, RegionConstructorData> constructorDataMap = new HashMap<>();
|
private static Map<Class<? extends DynamicRegion>, RegionConstructorData> constructorDataMap = new HashMap<>();
|
||||||
public static Map<String, Class<? extends DynamicRegion>> identifierDataMap = new HashMap<>();
|
private static Map<String, Class<? extends DynamicRegion>> identifierDataMap = new HashMap<>();
|
||||||
|
|
||||||
|
public static RegionConstructorData getRegionConstructorByRegionClass(Class<?> regionClass) {
|
||||||
|
return constructorDataMap.get(regionClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<? extends DynamicRegion> getRegionClassByIdentifier(String identifier) {
|
||||||
|
return identifierDataMap.get(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasRegionClassForIdentifier(String identifier) {
|
||||||
|
return identifierDataMap.containsKey(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<String> allRegionIdentifiers() {
|
||||||
|
return Collections.unmodifiableSet(identifierDataMap.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
|
|||||||
+34
-16
@@ -132,7 +132,7 @@ public class DynamicRegionRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe add static method to DynamicRegionSystem
|
// TODO: Maybe add static method to DynamicRegionSystem
|
||||||
Class<? extends DynamicRegion> regionClass = DynamicRegionSystem.identifierDataMap.get(identifier);
|
Class<? extends DynamicRegion> regionClass = DynamicRegionSystem.getRegionClassByIdentifier(identifier);
|
||||||
if (regionClass == null) {
|
if (regionClass == null) {
|
||||||
RegionSystem.LOGGER.log(Level.SEVERE, "Failed to read region metadata file (region no longer exists)");
|
RegionSystem.LOGGER.log(Level.SEVERE, "Failed to read region metadata file (region no longer exists)");
|
||||||
continue;
|
continue;
|
||||||
@@ -172,20 +172,28 @@ public class DynamicRegionRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File getRegionDirectory(Region region) {
|
||||||
|
return new File(REGION_DATA_FOLDER, region.getID().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getBackupsTypeDirectory(Region region, RegionBackups.BackupType backupType) {
|
||||||
|
File regionDirectory = getRegionDirectory(region);
|
||||||
|
File backupsDirectory = new File(regionDirectory, BACKUPS_DIR_NAME);
|
||||||
|
return new File(backupsDirectory, backupType.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getBackupDirectory(Region region, RegionBackups.Backup backup) {
|
||||||
|
return new File(getBackupsTypeDirectory(region, backup.getType()), backup.getName());
|
||||||
|
}
|
||||||
|
|
||||||
public static void loadRegionData(Region region, RegionData regionData) {
|
public static void loadRegionData(Region region, RegionData regionData) {
|
||||||
File regionDirectory = new File(REGION_DATA_FOLDER, region.getID().toString());
|
File regionDirectory = getRegionDirectory(region);
|
||||||
if (!regionDirectory.exists()) return;
|
if (!regionDirectory.exists()) return;
|
||||||
loadRegionData(regionDirectory, regionData);
|
loadRegionData(regionDirectory, regionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadRegionData(Region region, RegionBackups.Backup backup, RegionData regionData) {
|
public static void loadRegionData(Region region, RegionBackups.Backup backup, RegionData regionData) {
|
||||||
File regionDirectory = new File(REGION_DATA_FOLDER, region.getID().toString());
|
File backupDirectory = getBackupDirectory(region, backup);
|
||||||
if (!regionDirectory.exists()) return;
|
|
||||||
File backupsDirectory = new File(regionDirectory, BACKUPS_DIR_NAME);
|
|
||||||
if (!backupsDirectory.exists()) return;
|
|
||||||
File backupsTypeDirectory = new File(backupsDirectory, backup.getType().name());
|
|
||||||
if (!backupsTypeDirectory.exists()) return;
|
|
||||||
File backupDirectory = new File(backupsTypeDirectory, backup.getName());
|
|
||||||
if (!backupDirectory.exists()) return;
|
if (!backupDirectory.exists()) return;
|
||||||
loadRegionData(backupDirectory, regionData);
|
loadRegionData(backupDirectory, regionData);
|
||||||
}
|
}
|
||||||
@@ -234,7 +242,7 @@ public class DynamicRegionRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!region.getType().isGlobal()) {
|
if (!region.getType().isGlobal()) {
|
||||||
RegionConstructorData constructorData = DynamicRegionSystem.constructorDataMap.get(region.getClass());
|
RegionConstructorData constructorData = DynamicRegionSystem.getRegionConstructorByRegionClass(region.getClass());
|
||||||
Point point = region.getArea().getMinPoint(false);
|
Point point = region.getArea().getMinPoint(false);
|
||||||
Tile tile = Tile.fromPoint(point).get();
|
Tile tile = Tile.fromPoint(point).get();
|
||||||
|
|
||||||
@@ -242,7 +250,14 @@ public class DynamicRegionRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeFlagsFile(regionDirectory, region.getRegionData());
|
writeFlagsFile(regionDirectory, region.getRegionData());
|
||||||
// TODO: Write backups -> Directly on create!
|
}
|
||||||
|
|
||||||
|
public static void saveBackup(Region region, RegionBackups.Backup backup) {
|
||||||
|
File backupDirectory = getBackupDirectory(region, backup);
|
||||||
|
if (!backupDirectory.exists()) {
|
||||||
|
backupDirectory.mkdirs();
|
||||||
|
}
|
||||||
|
writeFlagsFile(backupDirectory, backup.getRegionData());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@@ -261,8 +276,8 @@ public class DynamicRegionRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private static void writeFlagsFile(File regionDirectory, RegionData regionData) {
|
private static void writeFlagsFile(File directory, RegionData regionData) {
|
||||||
JsonWriter jsonWriter = new JsonWriter(new FileWriter(new File(regionDirectory, FLAG_FILE_NAME)));
|
JsonWriter jsonWriter = new JsonWriter(new FileWriter(new File(directory, FLAG_FILE_NAME)));
|
||||||
jsonWriter.setIndent(" ");
|
jsonWriter.setIndent(" ");
|
||||||
jsonWriter.beginObject();
|
jsonWriter.beginObject();
|
||||||
|
|
||||||
@@ -285,12 +300,15 @@ public class DynamicRegionRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteRegion(Region region) {
|
public static void deleteRegion(Region region) {
|
||||||
File regionDirectory = new File(REGION_DATA_FOLDER, region.getID().toString());
|
deleteDir(getRegionDirectory(region));
|
||||||
deleteDir(regionDirectory);
|
}
|
||||||
|
|
||||||
|
public static void deleteBackup(Region region, RegionBackups.Backup backup) {
|
||||||
|
deleteDir(getBackupDirectory(region, backup));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static void deleteDir(File file) {
|
private static void deleteDir(File file) {
|
||||||
Files.walkFileTree(file.toPath(), new SimpleFileVisitor<>() {
|
Files.walkFileTree(file.toPath(), new SimpleFileVisitor<>() {
|
||||||
@Override
|
@Override
|
||||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
|
|||||||
+45
-25
@@ -20,17 +20,25 @@
|
|||||||
package de.steamwar.bausystem.region.dynamic.modes;
|
package de.steamwar.bausystem.region.dynamic.modes;
|
||||||
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||||
import de.steamwar.bausystem.region.RegionBackups;
|
import de.steamwar.bausystem.region.RegionBackups;
|
||||||
import de.steamwar.bausystem.region.RegionData;
|
import de.steamwar.bausystem.region.RegionData;
|
||||||
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
|
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
|
||||||
import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository;
|
import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository;
|
||||||
import de.steamwar.bausystem.region.dynamic.PasteUtils;
|
import de.steamwar.bausystem.region.dynamic.PasteUtils;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class PlotRegionBackups implements RegionBackups {
|
public class PlotRegionBackups implements RegionBackups {
|
||||||
|
|
||||||
@@ -46,7 +54,18 @@ public class PlotRegionBackups implements RegionBackups {
|
|||||||
this.region = region;
|
this.region = region;
|
||||||
this.regionDataConstructor = regionDataConstructor;
|
this.regionDataConstructor = regionDataConstructor;
|
||||||
|
|
||||||
// DynamicRegionRepository.loadRegionData();
|
// Load all Backups of the Region
|
||||||
|
for (BackupType backupType : BackupType.values()) {
|
||||||
|
File backupsTypeDirectory = DynamicRegionRepository.getBackupsTypeDirectory(region, backupType);
|
||||||
|
if (!backupsTypeDirectory.exists()) continue;
|
||||||
|
File[] backupsDirectory = backupsTypeDirectory.listFiles();
|
||||||
|
if (backupsDirectory == null) continue;
|
||||||
|
|
||||||
|
List<Backup> backupList = backups.computeIfAbsent(backupType, __ -> new ArrayList<>());
|
||||||
|
for (File backupDirectory : backupsDirectory) {
|
||||||
|
backupList.add(new BackupImpl(backupType, region, backupDirectory));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -60,11 +79,8 @@ public class PlotRegionBackups implements RegionBackups {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create backup and save!
|
// Create backup and save!
|
||||||
Backup backup = new BackupImpl(this, backupType, "", regionDataConstructor, region);
|
Backup backup = new BackupImpl(backupType, region);
|
||||||
// Create schematic and stuff?
|
|
||||||
backup.save();
|
|
||||||
backupList.add(backup);
|
backupList.add(backup);
|
||||||
|
|
||||||
return Optional.of(backup);
|
return Optional.of(backup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,20 +106,34 @@ public class PlotRegionBackups implements RegionBackups {
|
|||||||
|
|
||||||
private static final String SCHEM_FILE = "backup.schem";
|
private static final String SCHEM_FILE = "backup.schem";
|
||||||
|
|
||||||
private final PlotRegionBackups parent;
|
|
||||||
private final File folder;
|
|
||||||
private final DynamicRegion region;
|
private final DynamicRegion region;
|
||||||
|
|
||||||
public BackupImpl(PlotRegionBackups parent, @NonNull BackupType type, @NonNull String name, @NonNull Function<Backup, RegionData> regionDataConstructor, DynamicRegion region) {
|
public BackupImpl(@NonNull BackupType type, DynamicRegion region) {
|
||||||
super(type, name, regionDataConstructor);
|
super(type, LocalDateTime.now().format(FORMATTER), regionDataConstructor);
|
||||||
this.parent = parent;
|
region.getRegionData().copyInto(regionData);
|
||||||
folder = new File("");
|
|
||||||
this.region = region;
|
this.region = region;
|
||||||
|
|
||||||
|
File backupDirectory = DynamicRegionRepository.getBackupDirectory(region, this);
|
||||||
|
backupDirectory.mkdirs();
|
||||||
|
|
||||||
|
DynamicRegionRepository.saveBackup(region, this);
|
||||||
|
Clipboard clipboard = region.getArea().copy(false);
|
||||||
|
try (ClipboardWriter writer = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(new File(backupDirectory, SCHEM_FILE)))) {
|
||||||
|
writer.write(clipboard);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BackupImpl(@NonNull BackupType type, DynamicRegion region, File backupDirectory) {
|
||||||
|
super(type, backupDirectory.getName(), regionDataConstructor);
|
||||||
|
this.region = region;
|
||||||
|
DynamicRegionRepository.loadRegionData(region, this, regionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean load() {
|
public boolean load() {
|
||||||
File file = new File(folder, SCHEM_FILE);
|
File file = new File(DynamicRegionRepository.getBackupDirectory(region, this), SCHEM_FILE);
|
||||||
if (!file.exists()) return false;
|
if (!file.exists()) return false;
|
||||||
EditSession editSession = PasteUtils.paste(file, region.getArea().getMinPoint(false), 0);
|
EditSession editSession = PasteUtils.paste(file, region.getArea().getMinPoint(false), 0);
|
||||||
if (editSession == null) return false;
|
if (editSession == null) return false;
|
||||||
@@ -114,24 +144,14 @@ public class PlotRegionBackups implements RegionBackups {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getCreationTime() {
|
public long getCreationTime() {
|
||||||
throw new UnsupportedOperationException();
|
return DynamicRegionRepository.getBackupDirectory(region, this).lastModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
parent.backups.getOrDefault(type, Collections.emptyList())
|
backups.getOrDefault(type, Collections.emptyList())
|
||||||
.remove(this);
|
.remove(this);
|
||||||
DynamicRegionRepository.deleteDir(folder);
|
DynamicRegionRepository.deleteBackup(region, this);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(RegionData regionData) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-10
@@ -45,7 +45,6 @@ import java.util.stream.Collectors;
|
|||||||
public class FixedRegion implements Region {
|
public class FixedRegion implements Region {
|
||||||
|
|
||||||
private static final File backupFolder = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "backup");
|
private static final File backupFolder = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "backup");
|
||||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd' 'HH:mm:ss");
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
@@ -75,7 +74,7 @@ public class FixedRegion implements Region {
|
|||||||
while (files.size() >= 20) files.remove(0).delete();
|
while (files.size() >= 20) files.remove(0).delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
final File backupFile = new File(definedBackupFolder, LocalDateTime.now().format(formatter) + ".schem");
|
final File backupFile = new File(definedBackupFolder, LocalDateTime.now().format(FORMATTER) + ".schem");
|
||||||
Point minPoint = area.getMinPoint(false);
|
Point minPoint = area.getMinPoint(false);
|
||||||
Point maxPoint = area.getMaxPoint(false);
|
Point maxPoint = area.getMaxPoint(false);
|
||||||
if (!FlatteningWrapper.impl.backup(minPoint, maxPoint, backupFile)) {
|
if (!FlatteningWrapper.impl.backup(minPoint, maxPoint, backupFile)) {
|
||||||
@@ -138,14 +137,6 @@ public class FixedRegion implements Region {
|
|||||||
return file.lastModified();
|
return file.lastModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(RegionData regionData) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
file.delete();
|
file.delete();
|
||||||
|
|||||||
Reference in New Issue
Block a user