139 lines
5.6 KiB
Java
139 lines
5.6 KiB
Java
|
package net.minecraft.data.structures;
|
||
|
|
||
|
import com.google.common.collect.Lists;
|
||
|
import com.google.common.hash.HashCode;
|
||
|
import com.google.common.hash.Hashing;
|
||
|
import com.google.common.hash.HashingOutputStream;
|
||
|
import com.mojang.logging.LogUtils;
|
||
|
import java.io.BufferedReader;
|
||
|
import java.io.ByteArrayOutputStream;
|
||
|
import java.io.IOException;
|
||
|
import java.nio.file.Files;
|
||
|
import java.nio.file.Path;
|
||
|
import java.util.List;
|
||
|
import java.util.concurrent.CompletableFuture;
|
||
|
import java.util.stream.Stream;
|
||
|
import net.minecraft.Util;
|
||
|
import net.minecraft.data.CachedOutput;
|
||
|
import net.minecraft.data.DataProvider;
|
||
|
import net.minecraft.data.PackOutput;
|
||
|
import net.minecraft.nbt.CompoundTag;
|
||
|
import net.minecraft.nbt.NbtIo;
|
||
|
import net.minecraft.nbt.NbtUtils;
|
||
|
import org.apache.commons.io.IOUtils;
|
||
|
import org.slf4j.Logger;
|
||
|
|
||
|
public class SnbtToNbt implements DataProvider {
|
||
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||
|
private final PackOutput output;
|
||
|
private final Iterable<Path> inputFolders;
|
||
|
private final List<SnbtToNbt.Filter> filters = Lists.newArrayList();
|
||
|
|
||
|
public SnbtToNbt(PackOutput p_249104_, Iterable<Path> p_249523_) {
|
||
|
this.output = p_249104_;
|
||
|
this.inputFolders = p_249523_;
|
||
|
}
|
||
|
|
||
|
public SnbtToNbt addFilter(SnbtToNbt.Filter p_126476_) {
|
||
|
this.filters.add(p_126476_);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
private CompoundTag applyFilters(String p_126461_, CompoundTag p_126462_) {
|
||
|
CompoundTag compoundtag = p_126462_;
|
||
|
|
||
|
for (SnbtToNbt.Filter snbttonbt$filter : this.filters) {
|
||
|
compoundtag = snbttonbt$filter.apply(p_126461_, compoundtag);
|
||
|
}
|
||
|
|
||
|
return compoundtag;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public CompletableFuture<?> run(CachedOutput p_254336_) {
|
||
|
Path path = this.output.getOutputFolder();
|
||
|
List<CompletableFuture<?>> list = Lists.newArrayList();
|
||
|
|
||
|
for (Path path1 : this.inputFolders) {
|
||
|
list.add(
|
||
|
CompletableFuture.<CompletableFuture>supplyAsync(
|
||
|
() -> {
|
||
|
try {
|
||
|
CompletableFuture completablefuture;
|
||
|
try (Stream<Path> stream = Files.walk(path1)) {
|
||
|
completablefuture = CompletableFuture.allOf(
|
||
|
stream.filter(p_126464_ -> p_126464_.toString().endsWith(".snbt")).map(p_358468_ -> CompletableFuture.runAsync(() -> {
|
||
|
SnbtToNbt.TaskResult snbttonbt$taskresult = this.readStructure(p_358468_, this.getName(path1, p_358468_));
|
||
|
this.storeStructureIfChanged(p_254336_, snbttonbt$taskresult, path);
|
||
|
}, Util.backgroundExecutor().forName("SnbtToNbt"))).toArray(CompletableFuture[]::new)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return completablefuture;
|
||
|
} catch (Exception exception) {
|
||
|
throw new RuntimeException("Failed to read structure input directory, aborting", exception);
|
||
|
}
|
||
|
},
|
||
|
Util.backgroundExecutor().forName("SnbtToNbt")
|
||
|
)
|
||
|
.thenCompose(p_253441_ -> p_253441_)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return Util.sequenceFailFast(list);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public final String getName() {
|
||
|
return "SNBT -> NBT";
|
||
|
}
|
||
|
|
||
|
private String getName(Path p_126469_, Path p_126470_) {
|
||
|
String s = p_126469_.relativize(p_126470_).toString().replaceAll("\\\\", "/");
|
||
|
return s.substring(0, s.length() - ".snbt".length());
|
||
|
}
|
||
|
|
||
|
private SnbtToNbt.TaskResult readStructure(Path p_126466_, String p_126467_) {
|
||
|
try {
|
||
|
SnbtToNbt.TaskResult snbttonbt$taskresult;
|
||
|
try (BufferedReader bufferedreader = Files.newBufferedReader(p_126466_)) {
|
||
|
String s = IOUtils.toString(bufferedreader);
|
||
|
CompoundTag compoundtag = this.applyFilters(p_126467_, NbtUtils.snbtToStructure(s));
|
||
|
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
|
||
|
HashingOutputStream hashingoutputstream = new HashingOutputStream(Hashing.sha1(), bytearrayoutputstream);
|
||
|
NbtIo.writeCompressed(compoundtag, hashingoutputstream);
|
||
|
byte[] abyte = bytearrayoutputstream.toByteArray();
|
||
|
HashCode hashcode = hashingoutputstream.hash();
|
||
|
snbttonbt$taskresult = new SnbtToNbt.TaskResult(p_126467_, abyte, hashcode);
|
||
|
}
|
||
|
|
||
|
return snbttonbt$taskresult;
|
||
|
} catch (Throwable throwable1) {
|
||
|
throw new SnbtToNbt.StructureConversionException(p_126466_, throwable1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void storeStructureIfChanged(CachedOutput p_236394_, SnbtToNbt.TaskResult p_236395_, Path p_236396_) {
|
||
|
Path path = p_236396_.resolve(p_236395_.name + ".nbt");
|
||
|
|
||
|
try {
|
||
|
p_236394_.writeIfNeeded(path, p_236395_.payload, p_236395_.hash);
|
||
|
} catch (IOException ioexception) {
|
||
|
LOGGER.error("Couldn't write structure {} at {}", p_236395_.name, path, ioexception);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@FunctionalInterface
|
||
|
public interface Filter {
|
||
|
CompoundTag apply(String p_126480_, CompoundTag p_126481_);
|
||
|
}
|
||
|
|
||
|
static class StructureConversionException extends RuntimeException {
|
||
|
public StructureConversionException(Path p_176820_, Throwable p_176821_) {
|
||
|
super(p_176820_.toAbsolutePath().toString(), p_176821_);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
record TaskResult(String name, byte[] payload, HashCode hash) {
|
||
|
}
|
||
|
}
|