diff --git a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java index fca059d..6ef018d 100644 --- a/src/main/java/net/szum123321/textile_backup/ConfigHandler.java +++ b/src/main/java/net/szum123321/textile_backup/ConfigHandler.java @@ -23,9 +23,7 @@ import io.github.cottonmc.cotton.config.annotations.ConfigFile; import java.io.File; import java.time.format.DateTimeFormatter; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; +import java.util.*; @ConfigFile(name = Statics.MOD_ID) public class ConfigHandler { @@ -53,7 +51,7 @@ public class ConfigHandler { @Comment("\nThis setting allows you to exclude files form being backedup.\n"+ "Be very careful when setting it, as it is easy corrupt your world!\n") - public Set fileBlacklist = new HashSet<>(); + public List fileBlacklist = new ArrayList<>(); @Comment("\nShould backups be deleted after being restored?\n") public boolean deleteOldBackupAfterRestore = true; @@ -79,7 +77,8 @@ public class ConfigHandler { "ZIP - normal zip archive using standard deflate compression\n" + "GZIP - tar.gz using gzip compression\n" + "BZIP2 - tar.bz2 archive using bzip2 compression\n" + - "LZMA - tar.xz using lzma compression\n") + "LZMA - tar.xz using lzma compression\n" + + "TAR - .tar with no compression\n") public ArchiveFormat format = ArchiveFormat.ZIP; @Comment("\nMinimal permission level required to run commands\n") @@ -124,19 +123,32 @@ public class ConfigHandler { } public enum ArchiveFormat { - ZIP(".zip"), - GZIP(".tar.gz"), - BZIP2(".tar.bz2"), - LZMA(".tar.xz"); + ZIP("zip"), + GZIP("tar", "gz"), + BZIP2("tar", "bz2"), + LZMA("tar", "xz"), + TAR("tar"); - private final String extension; + private final List extensionPieces; - private ArchiveFormat(String extension){ - this.extension = extension; + ArchiveFormat(String... extensionParts) { + extensionPieces = Arrays.asList(extensionParts); } - public String getString() { - return extension; + public String getCompleteString() { + StringBuilder builder = new StringBuilder(); + + extensionPieces.forEach(s -> builder.append('.').append(s)); + + return builder.toString(); + } + + boolean isMultipart() { + return extensionPieces.size() > 1; + } + + public String getLastPiece() { + return extensionPieces.get(extensionPieces.size() - 1); } } } diff --git a/src/main/java/net/szum123321/textile_backup/core/Utilities.java b/src/main/java/net/szum123321/textile_backup/core/Utilities.java index 25c2d5b..d494358 100644 --- a/src/main/java/net/szum123321/textile_backup/core/Utilities.java +++ b/src/main/java/net/szum123321/textile_backup/core/Utilities.java @@ -34,6 +34,7 @@ import java.nio.file.Path; import java.nio.file.attribute.FileTime; import java.time.*; import java.time.format.DateTimeFormatter; +import java.util.Arrays; import java.util.Optional; public class Utilities { @@ -106,19 +107,9 @@ public class Utilities { public static Optional getArchiveExtension(String fileName) { String[] parts = fileName.split("\\."); - switch (parts[parts.length - 1]) { - case "zip": - return Optional.of(ConfigHandler.ArchiveFormat.ZIP); - case "bz2": - return Optional.of(ConfigHandler.ArchiveFormat.BZIP2); - case "gz": - return Optional.of(ConfigHandler.ArchiveFormat.GZIP); - case "xz": - return Optional.of(ConfigHandler.ArchiveFormat.LZMA); - - default: - return Optional.empty(); - } + return Arrays.stream(ConfigHandler.ArchiveFormat.values()) + .filter(format -> format.getLastPiece().equals(parts[parts.length - 1])) + .findAny(); } public static Optional getArchiveExtension(File f) { @@ -129,7 +120,7 @@ public class Utilities { LocalDateTime creationTime = null; if(getArchiveExtension(file).isPresent()) { - String fileExtension = getArchiveExtension(file).get().getString(); + String fileExtension = getArchiveExtension(file).get().getCompleteString(); try { creationTime = LocalDateTime.from( diff --git a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java index fec0221..0231a06 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/MakeBackupRunnable.java @@ -22,6 +22,7 @@ import net.szum123321.textile_backup.Statics; import net.szum123321.textile_backup.core.ActionInitiator; import net.szum123321.textile_backup.core.create.compressors.*; import net.szum123321.textile_backup.core.Utilities; +import net.szum123321.textile_backup.core.create.compressors.tar.AbstractTarArchiver; import net.szum123321.textile_backup.core.create.compressors.tar.LZMACompressor; import net.szum123321.textile_backup.core.create.compressors.tar.ParallelBZip2Compressor; import net.szum123321.textile_backup.core.create.compressors.tar.ParallelGzipCompressor; @@ -29,6 +30,7 @@ import net.szum123321.textile_backup.core.create.compressors.ParallelZipCompress import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.time.LocalDateTime; public class MakeBackupRunnable implements Runnable { @@ -101,6 +103,14 @@ public class MakeBackupRunnable implements Runnable { LZMACompressor.getInstance().createArchive(world, outFile, context, coreCount); break; + case TAR: + new AbstractTarArchiver() { + protected OutputStream getCompressorOutputStream(OutputStream stream, BackupContext ctx, int coreLimit) { + return stream; + } + }.createArchive(world, outFile, context, coreCount); + break; + default: Statics.LOGGER.warn("Specified compressor ({}) is not supported! Zip will be used instead!", Statics.CONFIG.format); @@ -124,6 +134,6 @@ public class MakeBackupRunnable implements Runnable { return Utilities.getDateTimeFormatter().format(now) + (context.getComment() != null ? "#" + context.getComment().replace("#", "") : "") + - Statics.CONFIG.format.getString(); + Statics.CONFIG.format.getCompleteString(); } } diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java index d7a14e3..cb89e0d 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/RestoreHelper.java @@ -96,7 +96,7 @@ public class RestoreHelper { private RestoreableFile(File file) throws NoSuchElementException { this.file = file; archiveFormat = Utilities.getArchiveExtension(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file extension!")); - String extension = archiveFormat.getString(); + String extension = archiveFormat.getCompleteString(); creationTime = Utilities.getFileCreationTime(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file creation time!")); final String filename = file.getName(); diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java index cbe4118..a305b5b 100644 --- a/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java +++ b/src/main/java/net/szum123321/textile_backup/core/restore/decompressors/GenericTarDecompressor.java @@ -23,7 +23,6 @@ import net.szum123321.textile_backup.core.Utilities; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.CompressorException; -import org.apache.commons.compress.compressors.CompressorInputStream; import org.apache.commons.compress.compressors.CompressorStreamFactory; import org.apache.commons.compress.utils.IOUtils; @@ -36,9 +35,9 @@ public class GenericTarDecompressor { public static void decompress(File input, File target) { Instant start = Instant.now(); - try (FileInputStream fileInputStream = new FileInputStream(input); - BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); - CompressorInputStream compressorInputStream = new CompressorStreamFactory().createCompressorInputStream(bufferedInputStream); + try (InputStream fileInputStream = new FileInputStream(input); + InputStream bufferedInputStream = new BufferedInputStream(fileInputStream); + InputStream compressorInputStream = getCompressorInputStream(bufferedInputStream); TarArchiveInputStream archiveInputStream = new TarArchiveInputStream(compressorInputStream)) { TarArchiveEntry entry; @@ -73,4 +72,26 @@ public class GenericTarDecompressor { Statics.LOGGER.info("Decompression took {} seconds.", Utilities.formatDuration(Duration.between(start, Instant.now()))); } + + private static InputStream getCompressorInputStream(InputStream inputStream) throws CompressorException { + try { + return new CompressorStreamFactory().createCompressorInputStream(inputStream); + } catch (CompressorException e) { + final byte[] tarHeader = new byte[512]; + int signatureLength; + + inputStream.mark(tarHeader.length); + + try { + signatureLength = IOUtils.readFully(inputStream, tarHeader); + inputStream.reset(); + } catch (IOException e1) { + throw new CompressorException("IOException while reading tar signature", e1); + } + + if(TarArchiveInputStream.matches(tarHeader, signatureLength)) return inputStream; + + throw e; + } + } } \ No newline at end of file