1
mirror of https://github.com/Shiewk/BlockHistory3.git synced 2026-04-28 04:24:17 +02:00

Added a command to approximate total disk space usage

This commit is contained in:
Shy
2025-03-14 14:52:06 +01:00
parent c33e508cf9
commit c577316920
3 changed files with 112 additions and 9 deletions
@@ -7,12 +7,13 @@ import de.shiewk.blockhistory.v3.util.BlockHistoryFileNames;
import de.shiewk.blockhistory.v3.util.NamedLoggingThreadFactory;
import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Objects;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletableFuture;
@@ -159,4 +160,61 @@ public final class HistoryManager {
}
}
}
public CompletableFuture<DiskSpaceApproximationVisitor> approximateDiskSpaceBytes() {
return CompletableFuture.supplyAsync(() -> {
try {
DiskSpaceApproximationVisitor visitor = new DiskSpaceApproximationVisitor();
Files.walkFileTree(saveDirectory, visitor);
return visitor;
} catch (IOException e) {
throw new RuntimeException(e);
}
}, readExecutor);
}
public static class DiskSpaceApproximationVisitor implements FileVisitor<Path> {
private long bytes = 0;
private long directories = 0;
private long files = 0;
public long getDiskSpaceBytes(){
return bytes;
}
public long getDirectoryCount() {
return directories;
}
public long getFileCount() {
return files;
}
@Override
public @NotNull FileVisitResult preVisitDirectory(Path dir, @NotNull BasicFileAttributes attrs) {
directories++;
bytes += dir.getFileName().toString().getBytes().length;
return FileVisitResult.CONTINUE;
}
@Override
public @NotNull FileVisitResult visitFile(Path file, @NotNull BasicFileAttributes attrs) {
files++;
bytes += file.getFileName().toString().getBytes().length;
bytes += file.toFile().length();
return FileVisitResult.CONTINUE;
}
@Override
public @NotNull FileVisitResult visitFileFailed(Path file, @NotNull IOException exc) throws IOException {
throw exc;
}
@Override
public @NotNull FileVisitResult postVisitDirectory(Path dir, @Nullable IOException exc) throws IOException {
if (exc != null) throw exc;
return FileVisitResult.CONTINUE;
}
}
}
@@ -41,6 +41,10 @@ public final class BlockHistoryCommand {
.requires(CommandUtil.requirePermission("blockhistory.command.stats"))
.executes(this::statsCommand)
)
.then(literal("diskspace")
.requires(CommandUtil.requirePermission("blockhistory.command.diskspace"))
.executes(this::approximateDiskSpace)
)
.then(literal("history")
.requires(CommandUtil.requirePermission("blockhistory.command.history"))
.then(argument("location", ArgumentTypes.blockPosition())
@@ -53,9 +57,45 @@ public final class BlockHistoryCommand {
.build();
}
private int approximateDiskSpace(CommandContext<CommandSourceStack> context) {
CommandSender sender = context.getSource().getSender();
sender.sendMessage(CHAT_PREFIX.append(
text("Approximating disk space usage, please wait... (this could take a while)", COLOR_PRIMARY)
));
try {
instance().getHistoryManager().approximateDiskSpaceBytes().whenComplete((result, throwable) -> {
if (throwable != null){
sender.sendMessage(CHAT_PREFIX.append(
text("This operation failed, please check the server logs.", COLOR_FAIL)
));
StringWriter strw = new StringWriter();
throwable.printStackTrace(new PrintWriter(strw));
logger().warn("Exception while approximating disk space:");
for (String s : strw.toString().split("\n")) {
logger().warn(s);
}
} else {
long bytes = result.getDiskSpaceBytes();
long directories = result.getDirectoryCount();
long files = result.getFileCount();
sender.sendMessage(CHAT_PREFIX.append(
text("Block history files use approximately ", COLOR_PRIMARY)
.append(text(UnitUtil.formatDataSize(bytes), COLOR_SECONDARY))
.append(text(" of disk space. "))
.append(text("(%s directories with %s files in total)".formatted(directories, files), NamedTextColor.GRAY))
));
}
});
} catch (RejectedExecutionException e) {
sender.sendMessage(text("The searching system is currently too busy, please try again later.", COLOR_FAIL));
}
return Command.SINGLE_SUCCESS;
}
private int statsCommand(CommandContext<CommandSourceStack> context) {
CommandSender sender = context.getSource().getSender();
StatManager statManager = BlockHistoryPlugin.instance().getStatManager();
StatManager statManager = instance().getStatManager();
long millisSinceStart = statManager.getTimeMsSinceStart();
sender.sendMessage(CHAT_PREFIX.append(
text("The plugin has started up ", COLOR_PRIMARY)
@@ -88,9 +128,9 @@ public final class BlockHistoryCommand {
StringWriter strw = new StringWriter();
e.printStackTrace(new PrintWriter(strw));
BlockHistoryPlugin.logger().warn("Exception while getting usable disk space:");
logger().warn("Exception while getting usable disk space:");
for (String s : strw.toString().split("\n")) {
BlockHistoryPlugin.logger().warn(s);
logger().warn(s);
}
}
return Command.SINGLE_SUCCESS;
@@ -125,9 +165,9 @@ public final class BlockHistoryCommand {
StringWriter strw = new StringWriter();
throwable.printStackTrace(new PrintWriter(strw));
BlockHistoryPlugin.logger().warn("Exception while searching block at world {} x {} y {} z {}:", searchedWorld, blockX, blockY, blockZ);
logger().warn("Exception while searching block at world {} x {} y {} z {}:", searchedWorld, blockX, blockY, blockZ);
for (String s : strw.toString().split("\n")) {
BlockHistoryPlugin.logger().warn(s);
logger().warn(s);
}
sender.sendMessage(CHAT_PREFIX.append(text("An error occurred while searching, please check the server console.\n", COLOR_FAIL)));
} else {
@@ -151,7 +191,7 @@ public final class BlockHistoryCommand {
@Override
public void onNoFilePresent(FileNotFoundException e) {
BlockHistoryPlugin.logger().info("No file present");
logger().info("No file present");
}
}
+5
View File
@@ -20,3 +20,8 @@ permissions:
description: Player can search the history of a block
children:
blockhistory.command.root: true
blockhistory.command.diskspace:
default: op
description: Player can approximate disk space usage
children:
blockhistory.command.root: true