minecraft-src/net/minecraft/server/packs/PathPackResources.java
2025-07-04 01:41:11 +03:00

192 lines
5.8 KiB
Java

package net.minecraft.server.packs;
import com.google.common.base.Joiner;
import com.google.common.collect.Sets;
import com.mojang.logging.LogUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
import net.minecraft.FileUtil;
import net.minecraft.Util;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.repository.Pack;
import net.minecraft.server.packs.resources.IoSupplier;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
public class PathPackResources extends AbstractPackResources {
private static final Logger LOGGER = LogUtils.getLogger();
private static final Joiner PATH_JOINER = Joiner.on("/");
private final Path root;
public PathPackResources(PackLocationInfo location, Path root) {
super(location);
this.root = root;
}
@Nullable
@Override
public IoSupplier<InputStream> getRootResource(String... elements) {
FileUtil.validatePath(elements);
Path path = FileUtil.resolvePath(this.root, List.of(elements));
return Files.exists(path, new LinkOption[0]) ? IoSupplier.create(path) : null;
}
public static boolean validatePath(Path path) {
return true;
}
@Nullable
@Override
public IoSupplier<InputStream> getResource(PackType packType, ResourceLocation location) {
Path path = this.root.resolve(packType.getDirectory()).resolve(location.getNamespace());
return getResource(location, path);
}
@Nullable
public static IoSupplier<InputStream> getResource(ResourceLocation location, Path path) {
return FileUtil.decomposePath(location.getPath()).mapOrElse(list -> {
Path path2 = FileUtil.resolvePath(path, list);
return returnFileIfExists(path2);
}, error -> {
LOGGER.error("Invalid path {}: {}", location, error.message());
return null;
});
}
@Nullable
private static IoSupplier<InputStream> returnFileIfExists(Path path) {
return Files.exists(path, new LinkOption[0]) && validatePath(path) ? IoSupplier.create(path) : null;
}
@Override
public void listResources(PackType packType, String namespace, String path, PackResources.ResourceOutput resourceOutput) {
FileUtil.decomposePath(path).ifSuccess(list -> {
Path pathx = this.root.resolve(packType.getDirectory()).resolve(namespace);
listPath(namespace, pathx, list, resourceOutput);
}).ifError(error -> LOGGER.error("Invalid path {}: {}", path, error.message()));
}
public static void listPath(String namespace, Path namespacePath, List<String> decomposedPath, PackResources.ResourceOutput resourceOutput) {
Path path = FileUtil.resolvePath(namespacePath, decomposedPath);
try {
Stream<Path> stream = Files.find(path, Integer.MAX_VALUE, (pathx, basicFileAttributes) -> basicFileAttributes.isRegularFile(), new FileVisitOption[0]);
try {
stream.forEach(path2 -> {
String string2 = PATH_JOINER.join(namespacePath.relativize(path2));
ResourceLocation resourceLocation = ResourceLocation.tryBuild(namespace, string2);
if (resourceLocation == null) {
Util.logAndPauseIfInIde(String.format(Locale.ROOT, "Invalid path in pack: %s:%s, ignoring", namespace, string2));
} else {
resourceOutput.accept(resourceLocation, IoSupplier.create(path2));
}
});
} catch (Throwable var9) {
if (stream != null) {
try {
stream.close();
} catch (Throwable var8) {
var9.addSuppressed(var8);
}
}
throw var9;
}
if (stream != null) {
stream.close();
}
} catch (NotDirectoryException | NoSuchFileException var10) {
} catch (IOException var11) {
LOGGER.error("Failed to list path {}", path, var11);
}
}
@Override
public Set<String> getNamespaces(PackType type) {
Set<String> set = Sets.<String>newHashSet();
Path path = this.root.resolve(type.getDirectory());
try {
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path);
try {
for (Path path2 : directoryStream) {
String string = path2.getFileName().toString();
if (ResourceLocation.isValidNamespace(string)) {
set.add(string);
} else {
LOGGER.warn("Non [a-z0-9_.-] character in namespace {} in pack {}, ignoring", string, this.root);
}
}
} catch (Throwable var9) {
if (directoryStream != null) {
try {
directoryStream.close();
} catch (Throwable var8) {
var9.addSuppressed(var8);
}
}
throw var9;
}
if (directoryStream != null) {
directoryStream.close();
}
} catch (NotDirectoryException | NoSuchFileException var10) {
} catch (IOException var11) {
LOGGER.error("Failed to list path {}", path, var11);
}
return set;
}
@Override
public void close() {
}
public static class PathResourcesSupplier implements Pack.ResourcesSupplier {
private final Path content;
public PathResourcesSupplier(Path content) {
this.content = content;
}
@Override
public PackResources openPrimary(PackLocationInfo location) {
return new PathPackResources(location, this.content);
}
@Override
public PackResources openFull(PackLocationInfo location, Pack.Metadata metadata) {
PackResources packResources = this.openPrimary(location);
List<String> list = metadata.overlays();
if (list.isEmpty()) {
return packResources;
} else {
List<PackResources> list2 = new ArrayList(list.size());
for (String string : list) {
Path path = this.content.resolve(string);
list2.add(new PathPackResources(location, path));
}
return new CompositePackResources(packResources, list2);
}
}
}
}