Initial version of multiple compression format system. Some more testing still required
This commit is contained in:
parent
226c75eefd
commit
be282adacf
@ -33,8 +33,9 @@ dependencies {
|
|||||||
include "io.github.cottonmc.cotton:cotton-logging:1.0.0-rc.4"
|
include "io.github.cottonmc.cotton:cotton-logging:1.0.0-rc.4"
|
||||||
include "io.github.cottonmc.cotton:cotton-config:1.0.0-rc.7"
|
include "io.github.cottonmc.cotton:cotton-config:1.0.0-rc.7"
|
||||||
|
|
||||||
include "org.apache.commons:commons-compress:1.9"
|
modCompile "org.apache.commons:commons-compress:1.20"
|
||||||
include "org.apache.commons:commons-io:1.3.2"
|
include "org.apache.commons:commons-compress:1.20"
|
||||||
|
//include "org.apache.commons:commons-io:1.3.2"
|
||||||
|
|
||||||
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
||||||
// You may need to force-disable transitiveness on them.
|
// You may need to force-disable transitiveness on them.
|
||||||
|
@ -9,6 +9,6 @@ loader_version=0.7.9+build.190
|
|||||||
fabric_version=0.5.7+build.314-1.16
|
fabric_version=0.5.7+build.314-1.16
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 1.1.1-1.15
|
mod_version = 1.2.0-1.15
|
||||||
maven_group = net.szum123321
|
maven_group = net.szum123321
|
||||||
archives_base_name = textile_backup
|
archives_base_name = textile_backup
|
@ -54,9 +54,16 @@ public class ConfigHandler {
|
|||||||
@Comment("\nMaximum size of backup folder in kilo bytes. \n")
|
@Comment("\nMaximum size of backup folder in kilo bytes. \n")
|
||||||
public int maxSize = 0;
|
public int maxSize = 0;
|
||||||
|
|
||||||
@Comment("\nCompression level \n0 - 9\n")
|
@Comment("\nCompression level \n0 - 9\n Only available for zip compression.\n")
|
||||||
public int compression = 1;
|
public int compression = 1;
|
||||||
|
|
||||||
|
@Comment(value = "\nAvailable formats are:\n" +
|
||||||
|
"ZIP - normal zip archive using standard deflate compression\n" +
|
||||||
|
"BZIP2 - tar.bz2 archive using bzip2 compression\n" +
|
||||||
|
"GIZP - tar.gz using gzip compression\n" +
|
||||||
|
"LZ4 - tar.lz using lz4 compression\n")
|
||||||
|
public ArchiveFormat format = ArchiveFormat.ZIP;
|
||||||
|
|
||||||
@Comment("\nPrint info to game out\n")
|
@Comment("\nPrint info to game out\n")
|
||||||
public boolean log = true;
|
public boolean log = true;
|
||||||
|
|
||||||
@ -74,4 +81,21 @@ public class ConfigHandler {
|
|||||||
|
|
||||||
@Comment("\nFormat of date&time used to name backup files.\n")
|
@Comment("\nFormat of date&time used to name backup files.\n")
|
||||||
public String dateTimeFormat = "dd.MM.yyyy_HH-mm-ss";
|
public String dateTimeFormat = "dd.MM.yyyy_HH-mm-ss";
|
||||||
|
|
||||||
|
public enum ArchiveFormat {
|
||||||
|
ZIP(".zip"),
|
||||||
|
BZIP2(".tar.bz2"),
|
||||||
|
GZIP(".tar.gz"),
|
||||||
|
LZ4(".tar.lz4");
|
||||||
|
|
||||||
|
private String extension;
|
||||||
|
|
||||||
|
private ArchiveFormat(String extension){
|
||||||
|
this.extension = extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExtension() {
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ package net.szum123321.textile_backup.commands;
|
|||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import net.minecraft.server.command.CommandManager;
|
import net.minecraft.server.command.CommandManager;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.text.LiteralText;
|
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import net.szum123321.textile_backup.core.BackupHelper;
|
import net.szum123321.textile_backup.core.BackupHelper;
|
||||||
|
|
||||||
@ -33,7 +32,6 @@ public class CleanupCommand {
|
|||||||
|
|
||||||
private static int execute(ServerCommandSource source){
|
private static int execute(ServerCommandSource source){
|
||||||
BackupHelper.executeFileLimit(source, source.getMinecraftServer().getWorld(DimensionType.OVERWORLD).getLevelProperties().getLevelName());
|
BackupHelper.executeFileLimit(source, source.getMinecraftServer().getWorld(DimensionType.OVERWORLD).getLevelProperties().getLevelName());
|
||||||
source.sendFeedback(new LiteralText("Done"), false);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -21,124 +21,155 @@ package net.szum123321.textile_backup.core;
|
|||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.szum123321.textile_backup.ConfigHandler;
|
||||||
import net.szum123321.textile_backup.TextileBackup;
|
import net.szum123321.textile_backup.TextileBackup;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileFilter;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.attribute.FileTime;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class BackupHelper {
|
public class BackupHelper {
|
||||||
public static void create(MinecraftServer server, ServerCommandSource ctx, boolean save, String comment) {
|
public static Thread create(MinecraftServer server, ServerCommandSource ctx, boolean save, String comment) {
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("Backup started by: ");
|
builder.append("Backup started by: ");
|
||||||
|
|
||||||
if( ctx != null )
|
if (ctx != null)
|
||||||
builder.append(ctx.getName());
|
builder.append(ctx.getName());
|
||||||
else
|
else
|
||||||
builder.append("SERVER");
|
builder.append("SERVER");
|
||||||
|
|
||||||
builder.append(" on: ");
|
builder.append(" on: ");
|
||||||
builder.append(Utilities.getDateTimeFormatter().format(now));
|
builder.append(Utilities.getDateTimeFormatter().format(now));
|
||||||
|
|
||||||
Utilities.log(builder.toString(), null);
|
Utilities.log(builder.toString(), null);
|
||||||
|
|
||||||
Utilities.log("Saving server...", ctx);
|
Utilities.log("Saving server...", ctx);
|
||||||
|
|
||||||
if(save)
|
if (save)
|
||||||
server.save(true, false, false);
|
server.save(true, true, false);
|
||||||
|
|
||||||
Thread thread = new Thread(new MakeBackupThread(server, ctx, comment));
|
Thread thread = new Thread(new MakeBackupThread(server, ctx, comment));
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
|
||||||
|
|
||||||
public static void executeFileLimit(ServerCommandSource ctx, String worldName){
|
return thread;
|
||||||
File root = getBackupRootPath(worldName);
|
}
|
||||||
|
|
||||||
FileFilter filter = f -> f.getName().endsWith("zip");
|
public static void executeFileLimit(ServerCommandSource ctx, String worldName) {
|
||||||
|
File root = getBackupRootPath(worldName);
|
||||||
|
|
||||||
if(root.isDirectory() && root.exists()){
|
if (root.isDirectory() && root.exists()) {
|
||||||
if(TextileBackup.config.maxAge > 0){
|
if (TextileBackup.config.maxAge > 0) {
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
|
||||||
Arrays.stream(root.listFiles()).forEach(f ->{
|
Arrays.stream(root.listFiles()).filter(f -> f.exists() && f.isFile()).forEach(f -> {
|
||||||
if(f.exists() && f.isFile()){
|
LocalDateTime creationTime = null;
|
||||||
LocalDateTime creationTime;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
creationTime = LocalDateTime.from(
|
try {
|
||||||
Utilities.getDateTimeFormatter().parse(
|
FileTime ct = (FileTime) Files.getAttribute(f.toPath(), "creationTime");
|
||||||
f.getName().split(".zip")[0].split("#")[0]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}catch(Exception e){
|
|
||||||
creationTime = LocalDateTime.from(
|
|
||||||
Utilities.getBackupDateTimeFormatter().parse(
|
|
||||||
f.getName().split(".zip")[0].split("#")[0]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
creationTime = LocalDateTime.ofInstant(ct.toInstant(), ZoneOffset.UTC);
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
try {
|
||||||
|
creationTime = LocalDateTime.from(
|
||||||
|
Utilities.getDateTimeFormatter().parse(
|
||||||
|
f.getName().split(Objects.requireNonNull(getFileExtension(f)))[0].split("#")[0]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} catch (Exception ignored2) {
|
||||||
|
creationTime = LocalDateTime.from(
|
||||||
|
Utilities.getBackupDateTimeFormatter().parse(
|
||||||
|
f.getName().split(Objects.requireNonNull(getFileExtension(f)))[0].split("#")[0]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(now.toEpochSecond(ZoneOffset.UTC) - creationTime.toEpochSecond(ZoneOffset.UTC) > TextileBackup.config.maxAge) {
|
if (now.toEpochSecond(ZoneOffset.UTC) - creationTime.toEpochSecond(ZoneOffset.UTC) > TextileBackup.config.maxAge) {
|
||||||
Utilities.log("Deleting: " + f.getName(), ctx);
|
Utilities.log("Deleting: " + f.getName(), ctx);
|
||||||
f.delete();
|
f.delete();
|
||||||
}
|
}
|
||||||
}
|
} catch (NullPointerException ignored3) {
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(TextileBackup.config.backupsToKeep > 0 && root.listFiles().length > TextileBackup.config.backupsToKeep){
|
if (TextileBackup.config.backupsToKeep > 0 && root.listFiles().length > TextileBackup.config.backupsToKeep) {
|
||||||
int var1 = root.listFiles().length - TextileBackup.config.backupsToKeep;
|
int var1 = root.listFiles().length - TextileBackup.config.backupsToKeep;
|
||||||
|
|
||||||
File[] files = root.listFiles(filter);
|
File[] files = root.listFiles();
|
||||||
assert files != null;
|
assert files != null;
|
||||||
|
|
||||||
Arrays.sort(files);
|
Arrays.sort(files);
|
||||||
|
|
||||||
for(int i = 0; i < var1; i++) {
|
for (int i = 0; i < var1; i++) {
|
||||||
Utilities.log("Deleting: " + files[i].getName(), ctx);
|
Utilities.log("Deleting: " + files[i].getName(), ctx);
|
||||||
files[i].delete();
|
files[i].delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(TextileBackup.config.maxSize > 0 && FileUtils.sizeOfDirectory(root) / 1024 > TextileBackup.config.maxSize){
|
if (TextileBackup.config.maxSize > 0 && FileUtils.sizeOfDirectory(root) / 1024 > TextileBackup.config.maxSize) {
|
||||||
Arrays.stream(root.listFiles()).sorted().forEach(e -> {
|
Arrays.stream(root.listFiles()).filter(File::isFile).sorted().forEach(e -> {
|
||||||
if(FileUtils.sizeOfDirectory(root) / 1024 > TextileBackup.config.maxSize){
|
if (FileUtils.sizeOfDirectory(root) / 1024 > TextileBackup.config.maxSize) {
|
||||||
Utilities.log("Deleting: " + e.getName(), ctx);
|
Utilities.log("Deleting: " + e.getName(), ctx);
|
||||||
e.delete();
|
e.delete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getBackupRootPath(String worldName){
|
private static String getFileExtension(File f) {
|
||||||
File path = new File(TextileBackup.config.path);
|
System.out.println(f.getName());
|
||||||
|
String[] parts = f.getName().split("\\.");
|
||||||
|
System.out.println(parts.length);
|
||||||
|
|
||||||
if(TextileBackup.config.perWorldBackup)
|
switch (parts[parts.length - 1]) {
|
||||||
path = path.toPath().resolve(worldName).toFile();
|
case "zip":
|
||||||
|
return ConfigHandler.ArchiveFormat.ZIP.getExtension();
|
||||||
|
case "bz2":
|
||||||
|
return ConfigHandler.ArchiveFormat.BZIP2.getExtension();
|
||||||
|
case "gz":
|
||||||
|
return ConfigHandler.ArchiveFormat.GZIP.getExtension();
|
||||||
|
case "lz4":
|
||||||
|
return ConfigHandler.ArchiveFormat.LZ4.getExtension();
|
||||||
|
|
||||||
if(!path.exists()){
|
default:
|
||||||
try{
|
return null;
|
||||||
path.mkdirs();
|
}
|
||||||
}catch(Exception e){
|
}
|
||||||
TextileBackup.logger.error(e.getMessage());
|
|
||||||
|
|
||||||
return FabricLoader
|
|
||||||
.getInstance()
|
|
||||||
.getGameDirectory()
|
|
||||||
.toPath()
|
|
||||||
.resolve(TextileBackup.config.path)
|
|
||||||
.toFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
public static File getBackupRootPath(String worldName) {
|
||||||
}
|
File path = new File(TextileBackup.config.path);
|
||||||
}
|
|
||||||
|
if (TextileBackup.config.perWorldBackup)
|
||||||
|
path = path.toPath().resolve(worldName).toFile();
|
||||||
|
|
||||||
|
if (!path.exists()) {
|
||||||
|
try {
|
||||||
|
path.mkdirs();
|
||||||
|
} catch (Exception e) {
|
||||||
|
TextileBackup.logger.error(e.getMessage());
|
||||||
|
|
||||||
|
return FabricLoader
|
||||||
|
.getInstance()
|
||||||
|
.getGameDirectory()
|
||||||
|
.toPath()
|
||||||
|
.resolve(TextileBackup.config.path)
|
||||||
|
.toFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
A simple backup mod for Fabric
|
|
||||||
Copyright (C) 2020 Szum123321
|
|
||||||
|
|
||||||
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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.szum123321.textile_backup.core;
|
|
||||||
|
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
|
||||||
import net.szum123321.textile_backup.TextileBackup;
|
|
||||||
import org.apache.commons.compress.utils.IOUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
public class Compressor {
|
|
||||||
public static void createArchive(File in, File out, ServerCommandSource ctx){
|
|
||||||
Utilities.log("Starting compression...", ctx);
|
|
||||||
|
|
||||||
try {
|
|
||||||
File input = in.getCanonicalFile();
|
|
||||||
|
|
||||||
ZipOutputStream arc = new ZipOutputStream(new FileOutputStream(out));
|
|
||||||
|
|
||||||
arc.setLevel(TextileBackup.config.compression);
|
|
||||||
arc.setComment("Created on: " + Utilities.getDateTimeFormatter().format(LocalDateTime.now()));
|
|
||||||
|
|
||||||
int rootPathLength = input.toString().length() + 1;
|
|
||||||
|
|
||||||
Files.walk(input.toPath()).filter(path -> !path.equals(input.toPath()) && path.toFile().isFile() && !TextileBackup.config.fileBlacklist.contains(path.toString().substring(rootPathLength))).forEach(path -> {
|
|
||||||
try{
|
|
||||||
File file = path.toAbsolutePath().toFile();
|
|
||||||
|
|
||||||
ZipEntry entry = new ZipEntry(file.getAbsolutePath().substring(rootPathLength));
|
|
||||||
arc.putNextEntry(entry);
|
|
||||||
entry.setSize(file.length());
|
|
||||||
IOUtils.copy(new FileInputStream(file), arc);
|
|
||||||
arc.closeEntry();
|
|
||||||
}catch (IOException e){
|
|
||||||
TextileBackup.logger.error(e.getMessage());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
arc.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
TextileBackup.logger.error(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
Utilities.log("Compression finished", ctx);
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,6 +21,12 @@ package net.szum123321.textile_backup.core;
|
|||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.szum123321.textile_backup.TextileBackup;
|
||||||
|
import net.szum123321.textile_backup.core.compressors.GenericTarCompressor;
|
||||||
|
import net.szum123321.textile_backup.core.compressors.ZipCompressor;
|
||||||
|
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
|
||||||
|
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
|
||||||
|
import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorOutputStream;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -59,7 +65,29 @@ public class MakeBackupThread implements Runnable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipCompressor.createArchive(world, outFile, ctx);
|
switch (TextileBackup.config.format) {
|
||||||
|
case ZIP:
|
||||||
|
ZipCompressor.createArchive(world, outFile, ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BZIP2:
|
||||||
|
GenericTarCompressor.createArchive(world, outFile, BZip2CompressorOutputStream.class, ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GZIP:
|
||||||
|
GenericTarCompressor.createArchive(world, outFile, GzipCompressorOutputStream.class, ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LZ4:
|
||||||
|
GenericTarCompressor.createArchive(world, outFile, FramedLZ4CompressorOutputStream.class, ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Utilities.log("Error! No compression format specified! using default compressor!", ctx);
|
||||||
|
ZipCompressor.createArchive(world, outFile, ctx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BackupHelper.executeFileLimit(ctx, server.getWorld(DimensionType.OVERWORLD).getLevelProperties().getLevelName());
|
BackupHelper.executeFileLimit(ctx, server.getWorld(DimensionType.OVERWORLD).getLevelProperties().getLevelName());
|
||||||
|
|
||||||
@ -69,6 +97,6 @@ public class MakeBackupThread implements Runnable {
|
|||||||
private String getFileName(){
|
private String getFileName(){
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
|
||||||
return Utilities.getDateTimeFormatter().format(now) + (comment != null ? "#" + comment.replace("#", ""): "") + ".zip";
|
return Utilities.getDateTimeFormatter().format(now) + (comment != null ? "#" + comment.replace("#", ""): "") + TextileBackup.config.format.getExtension();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package net.szum123321.textile_backup.core.compressors;
|
||||||
|
|
||||||
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.szum123321.textile_backup.TextileBackup;
|
||||||
|
import net.szum123321.textile_backup.core.Utilities;
|
||||||
|
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||||
|
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||||
|
import org.apache.commons.compress.compressors.CompressorOutputStream;
|
||||||
|
import org.apache.commons.compress.utils.IOUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
public class GenericTarCompressor {
|
||||||
|
public static void createArchive(File in, File out, Class<? extends CompressorOutputStream> CompressorStreamClass, ServerCommandSource ctx) {
|
||||||
|
Utilities.log("Starting compression...", ctx);
|
||||||
|
|
||||||
|
try (FileOutputStream outStream = new FileOutputStream(out);
|
||||||
|
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outStream);
|
||||||
|
CompressorOutputStream lz4Stream = CompressorStreamClass.getDeclaredConstructor(OutputStream.class).newInstance(bufferedOutputStream);// CompressorStreamClass.getConstructor().newInstance(bufferedOutputStream);
|
||||||
|
TarArchiveOutputStream arc = new TarArchiveOutputStream(lz4Stream)) {
|
||||||
|
|
||||||
|
System.out.println(lz4Stream.getClass().toString());
|
||||||
|
|
||||||
|
arc.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
|
||||||
|
arc.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
|
||||||
|
|
||||||
|
File input = in.getCanonicalFile();
|
||||||
|
int rootPathLength = input.toString().length() + 1;
|
||||||
|
|
||||||
|
Files.walk(input.toPath()).filter(
|
||||||
|
path -> !path.equals(input.toPath()) &&
|
||||||
|
path.toFile().isFile() &&
|
||||||
|
!TextileBackup.config.fileBlacklist.contains(path.toString().substring(rootPathLength))
|
||||||
|
).forEach(path -> {
|
||||||
|
File file = path.toAbsolutePath().toFile();
|
||||||
|
|
||||||
|
try (FileInputStream fin = new FileInputStream(file);
|
||||||
|
BufferedInputStream bfin = new BufferedInputStream(fin)){
|
||||||
|
TarArchiveEntry entry = new TarArchiveEntry(file, file.getAbsolutePath().substring(rootPathLength));
|
||||||
|
|
||||||
|
entry.setSize(file.length());
|
||||||
|
arc.putArchiveEntry(entry);
|
||||||
|
IOUtils.copy(bfin, arc);
|
||||||
|
|
||||||
|
arc.closeArchiveEntry();
|
||||||
|
} catch (IOException e) {
|
||||||
|
TextileBackup.logger.error(e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
TextileBackup.logger.error(e.getMessage());
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
Utilities.log("Compression finished", ctx);
|
||||||
|
}
|
||||||
|
}
|
@ -16,29 +16,29 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.szum123321.textile_backup.core;
|
package net.szum123321.textile_backup.core.compressors;
|
||||||
|
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.szum123321.textile_backup.TextileBackup;
|
import net.szum123321.textile_backup.TextileBackup;
|
||||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
import net.szum123321.textile_backup.core.Utilities;
|
||||||
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||||
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||||
import org.apache.commons.compress.utils.IOUtils;
|
import org.apache.commons.compress.utils.IOUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
public class ZipCompressor {
|
public class ZipCompressor {
|
||||||
public static void createArchive(File in, File out, ServerCommandSource ctx){
|
public static void createArchive(File in, File out, ServerCommandSource ctx){
|
||||||
Utilities.log("Starting compression...", ctx);
|
Utilities.log("Starting compression...", ctx);
|
||||||
|
|
||||||
try (ZipOutputStream arc = new ZipOutputStream(new FileOutputStream(out))){
|
try (FileOutputStream fileOutputStream = new FileOutputStream(out);
|
||||||
|
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
|
||||||
|
ZipArchiveOutputStream arc = new ZipArchiveOutputStream(bufferedOutputStream)){
|
||||||
|
|
||||||
|
arc.setMethod(ZipArchiveOutputStream.DEFLATED);
|
||||||
arc.setLevel(TextileBackup.config.compression);
|
arc.setLevel(TextileBackup.config.compression);
|
||||||
arc.setComment("Created on: " + Utilities.getDateTimeFormatter().format(LocalDateTime.now()));
|
arc.setComment("Created on: " + Utilities.getDateTimeFormatter().format(LocalDateTime.now()));
|
||||||
|
|
||||||
@ -46,19 +46,20 @@ public class ZipCompressor {
|
|||||||
int rootPathLength = input.toString().length() + 1;
|
int rootPathLength = input.toString().length() + 1;
|
||||||
|
|
||||||
Files.walk(input.toPath()).filter(path -> !path.equals(input.toPath()) && path.toFile().isFile() && !TextileBackup.config.fileBlacklist.contains(path.toString().substring(rootPathLength))).forEach(path -> {
|
Files.walk(input.toPath()).filter(path -> !path.equals(input.toPath()) && path.toFile().isFile() && !TextileBackup.config.fileBlacklist.contains(path.toString().substring(rootPathLength))).forEach(path -> {
|
||||||
try{
|
File file = path.toAbsolutePath().toFile();
|
||||||
File file = path.toAbsolutePath().toFile();
|
try (FileInputStream fstream = new FileInputStream(file)) {
|
||||||
|
ZipArchiveEntry entry = new ZipArchiveEntry(file, file.getAbsolutePath().substring(rootPathLength));
|
||||||
|
arc.putArchiveEntry(entry);
|
||||||
|
|
||||||
ZipEntry entry = new ZipEntry(file.getAbsolutePath().substring(rootPathLength));
|
IOUtils.copy(fstream, arc);
|
||||||
arc.putNextEntry(entry);
|
|
||||||
entry.setSize(file.length());
|
arc.closeArchiveEntry();
|
||||||
IOUtils.copy(new FileInputStream(file), arc);
|
|
||||||
arc.closeEntry();
|
|
||||||
}catch (IOException e){
|
}catch (IOException e){
|
||||||
TextileBackup.logger.error(e.getMessage());
|
TextileBackup.logger.error(e.getMessage());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
arc.finish();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
TextileBackup.logger.error(e.getMessage());
|
TextileBackup.logger.error(e.getMessage());
|
||||||
}
|
}
|
@ -52,7 +52,12 @@ public abstract class MinecraftServerMixin {
|
|||||||
|
|
||||||
@Inject(method = "shutdown", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;save(ZZZ)Z"))
|
@Inject(method = "shutdown", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;save(ZZZ)Z"))
|
||||||
public void onShutdown(CallbackInfo ci){
|
public void onShutdown(CallbackInfo ci){
|
||||||
if(TextileBackup.config.shutdownBackup)
|
if(TextileBackup.config.shutdownBackup) {
|
||||||
BackupHelper.create((MinecraftServer)(Object)this, null, false, null);
|
try {
|
||||||
|
BackupHelper.create((MinecraftServer) (Object) this, null, false, "shutdown").join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user