diff --git a/src/main/java/foxz/command/CmdCompressor.java b/src/main/java/foxz/command/CmdCompressor.java new file mode 100644 index 000000000..630d332d5 --- /dev/null +++ b/src/main/java/foxz/command/CmdCompressor.java @@ -0,0 +1,185 @@ +package foxz.command; + +import foxz.commandhelper.ChMcLogger; +import foxz.commandhelper.annotations.Command; +import foxz.commandhelper.annotations.SubCommand; +import foxz.commandhelper.permissions.OpOnly; +import me.luizotavio.compressor.ZstdCompressor; +import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.controllers.PlayerDataController; +import noppes.npcs.util.NBTJsonUtil; + +import java.io.File; +import java.io.RandomAccessFile; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static me.luizotavio.compressor.executor.IOExecutor.IO_EXECUTOR; + +@Command( + name = "compressor", + desc = "Convert a file to a compressed file and vice versa", + usage = "update [file|all] [json|zstd]" +) +public class CmdCompressor extends ChMcLogger { + + public CmdCompressor(Object sender) { + super(sender); + } + + @SubCommand( + name = "update", + desc = "Convert all files in the current directory to compressed files", + permissions = {OpOnly.class} + ) + public boolean onConvert(String[] args) throws ExecutionException, InterruptedException, TimeoutException { + if (args.length == 1) { + sendmessage("Please specify the type of compression to use"); + return true; + } + + String type; + + if (args[1].equalsIgnoreCase("json")) { + type = "json"; + } else if (args[1].equalsIgnoreCase("zstd")) { + type = "zstd"; + } else { + sendmessage("Please specify the type of compression to use"); + return true; + } + + File directory = PlayerDataController.instance.getSaveDir(); + + if (args[0].equalsIgnoreCase("all")) { + for (File file : directory.listFiles()) { + if (file.isDirectory()) { + continue; + } + + if (!file.getName().endsWith(".json") && type.equalsIgnoreCase("json")) { + submit(() -> { + try { + NBTTagCompound compound = NBTJsonUtil.LoadFile(file); + + File compressed = new File(file.getParentFile(), file.getName().replace(".json", ".zstd")); + + byte[] bytes = ZstdCompressor.writeCompound(compound); + + Files.write( + compressed.toPath(), + bytes, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE + ); + } catch (Exception exception) { + exception.printStackTrace(); + } + }); + } else if (!file.getName().endsWith(".zstd") && type.equalsIgnoreCase("zstd")) { + submit(() -> { + try { + NBTTagCompound compound = ZstdCompressor.readCompressCompound( + new RandomAccessFile(file, "r") + ); + + if (compound == null) { + return; + } + + File compressed = new File(file.getParentFile(), file.getName().replace(".zstd", ".json")); + + NBTJsonUtil.SaveFile(compressed, compound); + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + } + + sendmessage("Done! Almost file was converted."); + } else { + File file = new File(directory, args[0] + ".json"); + + if (!file.exists()) { + file = new File(directory, args[0] + ".zstd"); + } + + if (!file.exists()) { + sendmessage("File not found"); + return true; + } + + File finalFile = file; + + if (file.getName().endsWith(".json")) { + if (type.equalsIgnoreCase("json")) { + sendmessage("File is already in json format"); + return true; + } + + submit(() -> { + try { + NBTTagCompound compound = NBTJsonUtil.LoadFile(finalFile); + + File compressed = new File(finalFile.getParentFile(), finalFile.getName().replace(".json", ".zstd")); + + byte[] bytes = ZstdCompressor.writeCompound(compound); + + Files.write( + compressed.toPath(), + bytes, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE + ); + + sendmessage("File compressed to zstd!"); + } catch (Exception exception) { + exception.printStackTrace(); + } + }); + } + + if (file.getName().endsWith(".zstd")) { + if (type.equalsIgnoreCase("zstd")) { + sendmessage("File is already in zstd format"); + return true; + } + + submit(() -> { + try { + NBTTagCompound compound = ZstdCompressor.readCompressCompound( + new RandomAccessFile(finalFile, "r") + ); + + if (compound == null) { + return; + } + + File compressed = new File(finalFile.getParentFile(), finalFile.getName().replace(".zstd", ".json")); + + NBTJsonUtil.SaveFile(compressed, compound); + + sendmessage("File converted to json!"); + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + } + + return true; + } + + private void submit(Runnable runnable) throws ExecutionException, InterruptedException, TimeoutException { + CompletableFuture.runAsync(runnable, IO_EXECUTOR).get(5, TimeUnit.MINUTES); + } + + +} diff --git a/src/main/java/foxz/command/CmdNoppes.java b/src/main/java/foxz/command/CmdNoppes.java index 9e95fe665..7ba24b61e 100644 --- a/src/main/java/foxz/command/CmdNoppes.java +++ b/src/main/java/foxz/command/CmdNoppes.java @@ -37,7 +37,7 @@ import foxz.commandhelper.permissions.PlayerOnly; @Command( name = "noppes", desc = "noppes root command", - sub = {CmdClone.class, CmdScript.class, CmdQuest.class, CmdDialog.class, CmdConfig.class} + sub = {CmdClone.class, CmdScript.class, CmdQuest.class, CmdDialog.class, CmdConfig.class, CmdCompressor.class} ) public class CmdNoppes extends ChMcLogger {