Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to only backup claimed chunks #101

Merged
merged 22 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c937ef1
switch backups to common compress lib & add max folder size config
Lyfts Jul 31, 2024
d4aaf7e
Change uncompressed backup to a STORED zip instead of folder
Lyfts Aug 2, 2024
8449402
disabled by default
Lyfts Aug 2, 2024
3cfa172
stringbuilder be gone
Lyfts Aug 2, 2024
6c5e812
custom-named backups should be deleted by default
Lyfts Aug 3, 2024
91ca07f
iterator isn't necessary anymore
Lyfts Aug 23, 2024
971d7e1
add option to only backup claimed chunks
Lyfts Aug 6, 2024
5b83777
no need to remap the ChunkDimPos' to long
Lyfts Sep 5, 2024
a6ee988
much more optimized solution for mapping claims to their region file
Lyfts Sep 5, 2024
5ee682e
Merge branch 'master' into backup-improvement
Dream-Master Sep 6, 2024
42c75c7
Merge branch 'master' into backup-only-claimed-chunks
Dream-Master Sep 6, 2024
71de244
Merge remote-tracking branch 'refs/remotes/upstream/master' into back…
Lyfts Sep 6, 2024
8182c27
update configs
Lyfts Sep 6, 2024
94d793d
Merge remote-tracking branch 'refs/remotes/upstream/master' into back…
Lyfts Sep 6, 2024
10f0af2
Merge branch 'refs/heads/backup-improvement' into backup-only-claimed…
Lyfts Sep 6, 2024
8377ee1
update configs
Lyfts Sep 6, 2024
6bc4060
Merge branch 'master' into backup-only-claimed-chunks
Dream-Master Sep 6, 2024
9250888
Merge branch 'master' into backup-only-claimed-chunks
Dream-Master Sep 9, 2024
cc18a9e
make backups fall back to using native java zip if commons compress i…
Lyfts Sep 9, 2024
a43b7d4
Merge remote-tracking branch 'upstream/backup-only-claimed-chunks' in…
Lyfts Sep 9, 2024
44f4a1c
Merge branch 'master' into backup-only-claimed-chunks
Dream-Master Sep 13, 2024
b67a749
Merge remote-tracking branch 'upstream/master' into backup-only-claim…
Lyfts Sep 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/main/java/serverutils/ServerUtilitiesConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,12 @@ public static class Backups {
@Config.Comment("Delete backups that have a custom name set through /backup start <name>")
@Config.DefaultBoolean(true)
public boolean delete_custom_name_backups;

@Config.Comment("""
Only include claimed chunks in backup.
Backups will be much faster and smaller, but any unclaimed chunk will be unrecoverable.""")
@Config.DefaultBoolean(false)
public boolean only_backup_claimed_chunks;
}

public static class Login {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/serverutils/data/ClaimedChunks.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ public Collection<ClaimedChunk> getAllChunks() {
return map.isEmpty() ? Collections.emptyList() : map.values();
}

public Set<ChunkDimPos> getAllClaimedPositions() {
return map.isEmpty() ? Collections.emptySet() : map.keySet();
}

public Set<ClaimedChunk> getTeamChunks(@Nullable ForgeTeam team, OptionalInt dimension, boolean includePending) {
if (team == null) {
return Collections.emptySet();
Expand Down
7 changes: 2 additions & 5 deletions src/main/java/serverutils/lib/math/ChunkDimPos.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@ public ChunkDimPos set(int x, int z, int dim) {
return this;
}

public ChunkDimPos set(long packedPos, int dim) {
this.posX = CoordinatePacker.unpackX(packedPos);
this.posZ = CoordinatePacker.unpackZ(packedPos);
this.dim = dim;
return this;
public ChunkDimPos set(long packed, int dim) {
return set(CoordinatePacker.unpackX(packed), CoordinatePacker.unpackZ(packed), dim);
}

public boolean equals(Object o) {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/serverutils/lib/util/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,8 @@ public static String getBaseName(File file) {
return index == -1 ? name : name.substring(0, index);
}
}

public static String getRelativePath(File dir, File file) {
return dir.getName() + File.separator + file.getAbsolutePath().substring(dir.getAbsolutePath().length() + 1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package serverutils.lib.util.compression;

import static serverutils.ServerUtilitiesConfig.backups;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.IOUtils;

public class CommonsCompressor implements ICompress {

private ArchiveOutputStream output;

@Override
public void createOutputStream(File file) throws IOException {
ZipArchiveOutputStream zaos = new ZipArchiveOutputStream(file);
if (backups.compression_level == 0) {
zaos.setMethod(ZipEntry.STORED);
} else {
zaos.setLevel(backups.compression_level);
}
output = zaos;
}

@Override
public void addFileToArchive(File file, String name) throws IOException {
ArchiveEntry entry = output.createArchiveEntry(file, name);
output.putArchiveEntry(entry);
try (FileInputStream fis = new FileInputStream(file)) {
IOUtils.copy(fis, output);
}
output.closeArchiveEntry();
}

@Override
public void close() throws Exception {
if (output != null) {
output.close();
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/serverutils/lib/util/compression/ICompress.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package serverutils.lib.util.compression;

import java.io.File;
import java.io.IOException;

public interface ICompress extends AutoCloseable {

void createOutputStream(File file) throws IOException;

void addFileToArchive(File file, String name) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package serverutils.lib.util.compression;

import static serverutils.ServerUtilitiesConfig.backups;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;

public class LegacyCompressor implements ICompress {

private ZipOutputStream output;

@Override
public void createOutputStream(File file) throws IOException {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file));
if (backups.compression_level == 0) {
zos.setMethod(ZipOutputStream.STORED);
} else {
zos.setLevel(backups.compression_level);
}

output = zos;
}

@Override
public void addFileToArchive(File file, String name) throws IOException {
ZipEntry entry = new ZipEntry(name);
output.putNextEntry(entry);
try (FileInputStream fis = new FileInputStream(file)) {
IOUtils.copy(fis, output);
}
output.closeEntry();
}

@Override
public void close() throws Exception {
if (output != null) {
output.close();
}
}
}
30 changes: 28 additions & 2 deletions src/main/java/serverutils/task/backup/BackupTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

Expand All @@ -21,15 +23,23 @@
import serverutils.ServerUtilities;
import serverutils.ServerUtilitiesConfig;
import serverutils.ServerUtilitiesNotifications;
import serverutils.data.ClaimedChunks;
import serverutils.lib.data.Universe;
import serverutils.lib.math.ChunkDimPos;
import serverutils.lib.math.Ticks;
import serverutils.lib.util.CommonUtils;
import serverutils.lib.util.FileUtils;
import serverutils.lib.util.ServerUtils;
import serverutils.lib.util.compression.CommonsCompressor;
import serverutils.lib.util.compression.ICompress;
import serverutils.lib.util.compression.LegacyCompressor;
import serverutils.task.Task;

public class BackupTask extends Task {

public static final Pattern BACKUP_NAME_PATTERN = Pattern.compile("\\d{4}-\\d{2}-\\d{2}-\\d{2}-\\d{2}-\\d{2}(.*)");
public static final File BACKUP_TEMP_FOLDER = new File("serverutilities/temp/");
private static final boolean useLegacy;
public static File backupsFolder;
public static ThreadBackup thread;
public static boolean hadPlayer = false;
Expand All @@ -43,6 +53,7 @@ public class BackupTask extends Task {
if (!backupsFolder.exists()) backupsFolder.mkdirs();
clearOldBackups();
ServerUtilities.LOGGER.info("Backups folder - {}", backupsFolder.getAbsolutePath());
useLegacy = !CommonUtils.getClassExists("org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream");
}

public BackupTask() {
Expand Down Expand Up @@ -96,11 +107,24 @@ public void execute(Universe universe) {

File worldDir = DimensionManager.getCurrentSaveRootDirectory();

Set<ChunkDimPos> backupChunks = new HashSet<>();
if (backups.only_backup_claimed_chunks && ClaimedChunks.isActive()) {
backupChunks.addAll(ClaimedChunks.instance.getAllClaimedPositions());
BACKUP_TEMP_FOLDER.mkdirs();
}

ICompress compressor;
if (useLegacy) {
compressor = new LegacyCompressor();
} else {
compressor = new CommonsCompressor();
}

if (backups.use_separate_thread) {
thread = new ThreadBackup(worldDir, customName);
thread = new ThreadBackup(compressor, worldDir, customName, backupChunks);
thread.start();
} else {
ThreadBackup.doBackup(worldDir, customName);
ThreadBackup.doBackup(compressor, worldDir, customName, backupChunks);
}
universe.scheduleTask(new BackupTask(true));
}
Expand Down Expand Up @@ -158,6 +182,8 @@ private void postBackup(Universe universe) {
}

clearOldBackups();
FileUtils.delete(BACKUP_TEMP_FOLDER);

thread = null;
try {
MinecraftServer server = ServerUtils.getServer();
Expand Down
Loading