Some additional tweaks to the compression system. Also file blacklist works now!

2.x-1.16
Szum123321 2020-04-17 10:20:47 +02:00
parent be282adacf
commit c74fc6c999
10 changed files with 92 additions and 91 deletions

View File

@ -15,14 +15,14 @@ Available operations are:
* whitelist - here you can add, remove and list player that are allowed to run any operation within this mod despite not having high enough permission level* * whitelist - here you can add, remove and list player that are allowed to run any operation within this mod despite not having high enough permission level*
* whitelist - here you can add, remove and list player that are not allowed to run any operation within this mod despite having high enough permission level* * whitelist - here you can add, remove and list player that are not allowed to run any operation within this mod despite having high enough permission level*
All of above can only be done by server admins(permission level 4 - configurable*) / player on single player with cheats on. All of the above can only be done by server admins(permission level 4 - configurable*) or player on a single player.
Feel free to use this mod in your modpack or on server! Feel free to use this mod in your modpack or on a server!
### Important ### Important
* Time format defaultly used by this mod is: dd.MM.yyyy_HH-mm-ss although it is configurable*. * Time format defaultly used by this mod is: dd.MM.yyyy_HH-mm-ss although it is configurable*.
* _This mod contains **Cotton Config** and its dependencies as jars in jar, which are property of **CottonMC**_. * _This mod contains **Cotton Config** and its dependencies as jars in a jar, which are property of **CottonMC**_.
\* - feature available since 1.1.0 \* - feature available since 1.1.0

View File

@ -35,10 +35,6 @@ dependencies {
modCompile "org.apache.commons:commons-compress:1.20" modCompile "org.apache.commons:commons-compress:1.20"
include "org.apache.commons:commons-compress:1.20" 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.
// You may need to force-disable transitiveness on them.
} }
processResources { processResources {

View File

@ -1,14 +1,14 @@
# Done to increase the memory available to gradle. # Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G org.gradle.jvmargs=-Xmx1G
minecraft_version=20w14a minecraft_version=1.15.2
yarn_mappings=20w14a+build.1 yarn_mappings=1.15.2+build.15
loader_version=0.7.9+build.190 loader_version=0.8.2+build.194
#Fabric api #Fabric api
fabric_version=0.5.7+build.314-1.16 fabric_version=0.5.1+build.294-1.15
# Mod Properties # Mod Properties
mod_version = 1.2.0-1.15 mod_version = 1.2.0B-1.15
maven_group = net.szum123321 maven_group = net.szum123321
archives_base_name = textile_backup archives_base_name = textile_backup

View File

@ -27,60 +27,60 @@ import java.util.Set;
@ConfigFile(name = TextileBackup.MOD_ID) @ConfigFile(name = TextileBackup.MOD_ID)
public class ConfigHandler { public class ConfigHandler {
@Comment("\nTime between backups in seconds\n") @Comment("\nTime between backups in seconds\n")
public long backupInterval = 3600; public final long backupInterval = 3600;
@Comment("\nShould backups be done even if there is no players?\n") @Comment("\nShould backups be done even if there is no players?\n")
public boolean doBackupsOnEmptyServer = false; public final boolean doBackupsOnEmptyServer = false;
@Comment("\nShould backups be made on server shutdown\n") @Comment("\nShould backups be made on server shutdown\n")
public boolean shutdownBackup = true; public final boolean shutdownBackup = true;
@Comment("\nA path to backup folder\n") @Comment("\nA path to backup folder\n")
public String path = "backup/"; public final String path = "backup/";
@Comment("\nThis setting allows you to exclude files form being backuped.\n"+ @Comment("\nThis setting allows you to exclude files form being backuped.\n"+
"Be very careful when setting it, as it is easy to make your backuped world unusable!\n") "Be very careful when setting it, as it is easy to make your backuped world unusable!\n")
public Set<String> fileBlacklist = new HashSet<>(); public final Set<String> fileBlacklist = new HashSet<>();
@Comment("\nShould every world has its won backup folder?\n") @Comment("\nShould every world has its won backup folder?\n")
public boolean perWorldBackup = false; public final boolean perWorldBackup = false;
@Comment("\nMaximum number of backups to keep. If 0 then no backup will be deleted based on its amount\n") @Comment("\nMaximum number of backups to keep. If 0 then no backup will be deleted based on its amount\n")
public int backupsToKeep = 10; public final int backupsToKeep = 10;
@Comment("\nMaximum age of backups to keep in seconds.\n if 0 then backups will not be deleted based on its age \n") @Comment("\nMaximum age of backups to keep in seconds.\n if 0 then backups will not be deleted based on its age \n")
public long maxAge = 0; public final long maxAge = 0;
@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 final int maxSize = 0;
@Comment("\nCompression level \n0 - 9\n Only available for zip compression.\n") @Comment("\nCompression level \n0 - 9\n Only available for zip compression.\n")
public int compression = 1; public final int compression = 1;
@Comment(value = "\nAvailable formats are:\n" + @Comment(value = "\nAvailable formats are:\n" +
"ZIP - normal zip archive using standard deflate compression\n" + "ZIP - normal zip archive using standard deflate compression\n" +
"BZIP2 - tar.bz2 archive using bzip2 compression\n" + "BZIP2 - tar.bz2 archive using bzip2 compression\n" +
"GIZP - tar.gz using gzip compression\n" + "GIZP - tar.gz using gzip compression\n" +
"LZ4 - tar.lz using lz4 compression\n") "LZ4 - tar.lz using lz4 compression\n")
public ArchiveFormat format = ArchiveFormat.ZIP; public final ArchiveFormat format = ArchiveFormat.ZIP;
@Comment("\nPrint info to game out\n") @Comment("\nPrint info to game out\n")
public boolean log = true; public final boolean log = true;
@Comment("\nMinimal permission level required to run commands\n") @Comment("\nMinimal permission level required to run commands\n")
public int permissionLevel = 4; public final int permissionLevel = 4;
@Comment("\nPlayer on singleplayer is always allowed to run command. Warning! On lan party everyone will be allowed to run it.\n") @Comment("\nPlayer on singleplayer is always allowed to run command. Warning! On lan party everyone will be allowed to run it.\n")
public boolean alwaysSingleplayerAllowed = true; public final boolean alwaysSingleplayerAllowed = true;
@Comment("\nPlayers allowed to run backup commands without sufficient permission level\n") @Comment("\nPlayers allowed to run backup commands without sufficient permission level\n")
public Set<String> playerWhitelist = new HashSet<>(); public final Set<String> playerWhitelist = new HashSet<>();
@Comment("\nPlayers banned from running backup commands besides their sufficient permission level\n") @Comment("\nPlayers banned from running backup commands besides their sufficient permission level\n")
public Set<String> playerBlacklist = new HashSet<>(); public final Set<String> playerBlacklist = new HashSet<>();
@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 final String dateTimeFormat = "dd.MM.yyyy_HH-mm-ss";
public enum ArchiveFormat { public enum ArchiveFormat {
ZIP(".zip"), ZIP(".zip"),
@ -88,7 +88,7 @@ public class ConfigHandler {
GZIP(".tar.gz"), GZIP(".tar.gz"),
LZ4(".tar.lz4"); LZ4(".tar.lz4");
private String extension; private final String extension;
private ArchiveFormat(String extension){ private ArchiveFormat(String extension){
this.extension = extension; this.extension = extension;
@ -97,5 +97,5 @@ public class ConfigHandler {
public String getExtension() { public String getExtension() {
return extension; return extension;
} }
}; }
} }

View File

@ -71,13 +71,13 @@ public class BackupHelper {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
Arrays.stream(root.listFiles()).filter(f -> f.exists() && f.isFile()).forEach(f -> { Arrays.stream(root.listFiles()).filter(f -> f.exists() && f.isFile()).forEach(f -> {
LocalDateTime creationTime = null; LocalDateTime creationTime;
try { try {
try { try {
FileTime ct = (FileTime) Files.getAttribute(f.toPath(), "creationTime"); FileTime fileTime = (FileTime) Files.getAttribute(f.toPath(), "creationTime");
creationTime = LocalDateTime.ofInstant(ct.toInstant(), ZoneOffset.UTC); creationTime = LocalDateTime.ofInstant(fileTime.toInstant(), ZoneOffset.UTC);
} catch (IOException ignored) { } catch (IOException ignored) {
try { try {
creationTime = LocalDateTime.from( creationTime = LocalDateTime.from(
@ -98,8 +98,7 @@ public class BackupHelper {
Utilities.log("Deleting: " + f.getName(), ctx); Utilities.log("Deleting: " + f.getName(), ctx);
f.delete(); f.delete();
} }
} catch (NullPointerException ignored3) { } catch (NullPointerException ignored3) {}
}
}); });
} }

View File

@ -33,9 +33,9 @@ import java.io.IOException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
public class MakeBackupThread implements Runnable { public class MakeBackupThread implements Runnable {
private MinecraftServer server; private final MinecraftServer server;
private ServerCommandSource ctx; private final ServerCommandSource ctx;
private String comment; private final String comment;
public MakeBackupThread(MinecraftServer server, ServerCommandSource ctx, String comment){ public MakeBackupThread(MinecraftServer server, ServerCommandSource ctx, String comment){
this.server = server; this.server = server;
@ -83,12 +83,11 @@ public class MakeBackupThread implements Runnable {
break; break;
default: default:
Utilities.log("Error! No compression format specified! using default compressor!", ctx); Utilities.log("Error! No correct compression format specified! using default compressor!", ctx);
ZipCompressor.createArchive(world, outFile, ctx); ZipCompressor.createArchive(world, outFile, ctx);
break; break;
} }
BackupHelper.executeFileLimit(ctx, server.getWorld(DimensionType.OVERWORLD).getLevelProperties().getLevelName()); BackupHelper.executeFileLimit(ctx, server.getWorld(DimensionType.OVERWORLD).getLevelProperties().getLevelName());
Utilities.log("Done!", ctx); Utilities.log("Done!", ctx);
@ -97,6 +96,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("#", ""): "") + TextileBackup.config.format.getExtension(); return Utilities.getDateTimeFormatter().format(now) + (comment != null ? "#" + comment.replace("#", "") : "") + TextileBackup.config.format.getExtension();
} }
} }

View File

@ -4,6 +4,7 @@ import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.szum123321.textile_backup.TextileBackup; import net.szum123321.textile_backup.TextileBackup;
import java.nio.file.Path;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
public class Utilities { public class Utilities {
@ -12,6 +13,15 @@ public class Utilities {
return os.toLowerCase().startsWith("win"); return os.toLowerCase().startsWith("win");
} }
public static boolean isBlacklisted(Path path) {
for(String i : TextileBackup.config.fileBlacklist) {
if(path.startsWith(i))
return true;
}
return false;
}
public static DateTimeFormatter getDateTimeFormatter(){ public static DateTimeFormatter getDateTimeFormatter(){
if(!TextileBackup.config.dateTimeFormat.equals("")) if(!TextileBackup.config.dateTimeFormat.equals(""))
return DateTimeFormatter.ofPattern(TextileBackup.config.dateTimeFormat); return DateTimeFormatter.ofPattern(TextileBackup.config.dateTimeFormat);

View File

@ -3,7 +3,7 @@ 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 net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.Utilities;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.CompressorOutputStream; import org.apache.commons.compress.compressors.CompressorOutputStream;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.compress.utils.IOUtils;
@ -18,10 +18,8 @@ public class GenericTarCompressor {
try (FileOutputStream outStream = new FileOutputStream(out); try (FileOutputStream outStream = new FileOutputStream(out);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outStream); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outStream);
CompressorOutputStream lz4Stream = CompressorStreamClass.getDeclaredConstructor(OutputStream.class).newInstance(bufferedOutputStream);// CompressorStreamClass.getConstructor().newInstance(bufferedOutputStream); CompressorOutputStream compressorStream = CompressorStreamClass.getDeclaredConstructor(OutputStream.class).newInstance(bufferedOutputStream);// CompressorStreamClass.getConstructor().newInstance(bufferedOutputStream);
TarArchiveOutputStream arc = new TarArchiveOutputStream(lz4Stream)) { TarArchiveOutputStream arc = new TarArchiveOutputStream(compressorStream)) {
System.out.println(lz4Stream.getClass().toString());
arc.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); arc.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
arc.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX); arc.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
@ -32,15 +30,14 @@ public class GenericTarCompressor {
Files.walk(input.toPath()).filter( Files.walk(input.toPath()).filter(
path -> !path.equals(input.toPath()) && path -> !path.equals(input.toPath()) &&
path.toFile().isFile() && path.toFile().isFile() &&
!TextileBackup.config.fileBlacklist.contains(path.toString().substring(rootPathLength)) !Utilities.isBlacklisted(input.toPath().relativize(path))
).forEach(path -> { ).forEach(path -> {
File file = path.toAbsolutePath().toFile(); File file = path.toAbsolutePath().toFile();
try (FileInputStream fin = new FileInputStream(file); try (FileInputStream fin = new FileInputStream(file);
BufferedInputStream bfin = new BufferedInputStream(fin)){ BufferedInputStream bfin = new BufferedInputStream(fin)){
TarArchiveEntry entry = new TarArchiveEntry(file, file.getAbsolutePath().substring(rootPathLength)); ArchiveEntry entry = arc.createArchiveEntry(file, file.getAbsolutePath().substring(rootPathLength));
entry.setSize(file.length());
arc.putArchiveEntry(entry); arc.putArchiveEntry(entry);
IOUtils.copy(bfin, arc); IOUtils.copy(bfin, arc);
@ -49,18 +46,11 @@ public class GenericTarCompressor {
TextileBackup.logger.error(e.getMessage()); TextileBackup.logger.error(e.getMessage());
} }
}); });
} catch (IOException e) { arc.finish();
TextileBackup.logger.error(e.getMessage()); } catch (IOException | IllegalAccessException | NoSuchMethodException | InstantiationException | InvocationTargetException e) {
} catch (IllegalAccessException e) { TextileBackup.logger.error(e.toString());
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} }
Utilities.log("Compression finished", ctx); Utilities.log("Compression finished", ctx);
} }
} }

View File

@ -21,7 +21,7 @@ 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 net.szum123321.textile_backup.core.Utilities; import net.szum123321.textile_backup.core.Utilities;
import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.compress.utils.IOUtils;
@ -31,39 +31,46 @@ import java.nio.file.Files;
import java.time.LocalDateTime; import java.time.LocalDateTime;
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 (FileOutputStream fileOutputStream = new FileOutputStream(out); try (FileOutputStream fileOutputStream = new FileOutputStream(out);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
ZipArchiveOutputStream arc = new ZipArchiveOutputStream(bufferedOutputStream)){ ZipArchiveOutputStream arc = new ZipArchiveOutputStream(bufferedOutputStream)) {
arc.setMethod(ZipArchiveOutputStream.DEFLATED); arc.setMethod(ZipArchiveOutputStream.DEFLATED);
arc.setLevel(TextileBackup.config.compression); arc.setUseZip64(Zip64Mode.AsNeeded);
arc.setComment("Created on: " + Utilities.getDateTimeFormatter().format(LocalDateTime.now())); arc.setLevel(TextileBackup.config.compression);
arc.setComment("Created on: " + Utilities.getDateTimeFormatter().format(LocalDateTime.now()));
File input = in.getCanonicalFile(); File input = in.getCanonicalFile();
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(
File file = path.toAbsolutePath().toFile(); path -> !path.equals(input.toPath()) &&
try (FileInputStream fstream = new FileInputStream(file)) { path.toFile().isFile() &&
ZipArchiveEntry entry = new ZipArchiveEntry(file, file.getAbsolutePath().substring(rootPathLength)); !Utilities.isBlacklisted(input.toPath().relativize(path))
arc.putArchiveEntry(entry); ).forEach(path -> {
File file = path.toAbsolutePath().toFile();
IOUtils.copy(fstream, arc); try (FileInputStream fin = new FileInputStream(file);
BufferedInputStream bfin = new BufferedInputStream(fin)) {
ZipArchiveEntry entry = new ZipArchiveEntry(file, file.getAbsolutePath().substring(rootPathLength));
arc.closeArchiveEntry(); arc.putArchiveEntry(entry);
}catch (IOException e){ IOUtils.copy(bfin, arc);
TextileBackup.logger.error(e.getMessage());
}
});
arc.finish(); arc.closeArchiveEntry();
} catch (IOException e) { } catch (IOException e) {
TextileBackup.logger.error(e.getMessage()); TextileBackup.logger.error(e.getMessage());
} }
});
Utilities.log("Compression finished", ctx); arc.finish();
} } catch (IOException e) {
} TextileBackup.logger.error(e.getMessage());
}
Utilities.log("Compression finished", ctx);
}
}

View File

@ -29,6 +29,6 @@
"depends": { "depends": {
"fabricloader": ">=0.7.2", "fabricloader": ">=0.7.2",
"fabric": "*", "fabric": "*",
"minecraft": "1.16.*" "minecraft": "1.15.*"
} }
} }