AssetsDuplicatesCommand.java
package com.hypixel.hytale.server.core.command.commands.debug;
import com.hypixel.hytale.common.util.FormatUtil;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.common.CommonAsset;
import com.hypixel.hytale.server.core.asset.common.CommonAssetRegistry;
import com.hypixel.hytale.server.core.asset.common.asset.FileCommonAsset;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractAsyncCommand;
import com.hypixel.hytale.server.core.util.message.MessageFormat;
import com.hypixel.hytale.sneakythrow.SneakyThrow;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
public class AssetsDuplicatesCommand extends AbstractAsyncCommand {
@Nonnull
private final FlagArg reverseFlag = this.withFlagArg("reverse", "server.commands.assets.duplicates.reverse.desc");
public AssetsDuplicatesCommand() {
super("duplicates", "server.commands.assets.duplicates.desc");
}
@Nonnull
protected CompletableFuture<Void> executeAsync(@Nonnull CommandContext context) {
boolean reverse = (Boolean)this.reverseFlag.get(context);
List<CompletableFuture<Void>> futures = new ObjectArrayList<CompletableFuture<Void>>();
List<DuplicatedAssetInfo> duplicates = new ObjectArrayList<DuplicatedAssetInfo>();
for(Map.Entry<String, List<CommonAssetRegistry.PackAsset>> entry : CommonAssetRegistry.getDuplicatedAssets().entrySet()) {
DuplicatedAssetInfo duplicateInfo = new DuplicatedAssetInfo((String)entry.getKey(), (List)entry.getValue());
duplicates.add(duplicateInfo);
futures.add(duplicateInfo.calculateTotalSize());
}
return CompletableFuture.allOf((CompletableFuture[])futures.toArray((x$0) -> new CompletableFuture[x$0])).thenAccept((aVoid) -> {
duplicates.sort(reverse ? AssetsDuplicatesCommand.DuplicatedAssetInfo.COMPARATOR_REVERSE : AssetsDuplicatesCommand.DuplicatedAssetInfo.COMPARATOR);
long totalWastedSpace = 0L;
for(DuplicatedAssetInfo duplicateInfo : duplicates) {
Message header = Message.translation("server.commands.assets.duplicates.header").param("hash", duplicateInfo.hash).param("wastedBytes", FormatUtil.bytesToString(duplicateInfo.wastedSpace));
Set<Message> duplicateAssets = (Set)duplicateInfo.assets.stream().map((a) -> {
String var10000 = a.pack();
return var10000 + ":" + a.asset().getName();
}).map(Message::raw).collect(Collectors.toSet());
context.sendMessage(MessageFormat.list(header, duplicateAssets));
totalWastedSpace += duplicateInfo.wastedSpace;
}
context.sendMessage(Message.translation("server.commands.assets.duplicates.total").param("wastedBytes", FormatUtil.bytesToString(totalWastedSpace)));
});
}
public static class DuplicatedAssetInfo {
@Nonnull
public static final Comparator<DuplicatedAssetInfo> COMPARATOR = Comparator.comparingLong((o) -> o.wastedSpace);
@Nonnull
public static final Comparator<DuplicatedAssetInfo> COMPARATOR_REVERSE;
@Nonnull
final String hash;
@Nonnull
final List<CommonAssetRegistry.PackAsset> assets;
long wastedSpace;
public DuplicatedAssetInfo(@Nonnull String hash, @Nonnull List<CommonAssetRegistry.PackAsset> assets) {
this.hash = hash;
this.assets = assets;
}
@Nonnull
public CompletableFuture<Void> calculateTotalSize() {
CommonAsset commonAsset = ((CommonAssetRegistry.PackAsset)this.assets.getFirst()).asset();
if (commonAsset instanceof FileCommonAsset fileCommonAsset) {
Path path = fileCommonAsset.getFile();
return CompletableFuture.runAsync(SneakyThrow.sneakyRunnable(() -> this.wastedSpace = Files.size(path) * (long)(this.assets.size() - 1)));
} else {
return commonAsset.getBlob().thenAccept((bytes) -> this.wastedSpace = (long)bytes.length * (long)(this.assets.size() - 1));
}
}
static {
COMPARATOR_REVERSE = Collections.reverseOrder(COMPARATOR);
}
}
}