FilePackResources.java

net.minecraft.server.packs.FilePackResources

信息

  • 全限定名:net.minecraft.server.packs.FilePackResources
  • 类型:public class
  • 包:net.minecraft.server.packs
  • 源码路径:src/main/java/net/minecraft/server/packs/FilePackResources.java
  • 起始行号:L24
  • 继承:AbstractPackResources
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L25
    • 说明:

      TODO

  • zipFileAccess

    • 类型: FilePackResources.SharedZipFileAccess
    • 修饰符: private final
    • 源码定位: L26
    • 说明:

      TODO

  • prefix

    • 类型: String
    • 修饰符: private final
    • 源码定位: L27
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.server.packs.FilePackResources.FileResourcesSupplier

    • 类型: class
    • 修饰符: public static
    • 源码定位: L132
    • 说明:

      TODO

  • net.minecraft.server.packs.FilePackResources.SharedZipFileAccess

    • 类型: class
    • 修饰符: private static
    • 源码定位: L168
    • 说明:

      TODO

构造器

private FilePackResources(PackLocationInfo location, FilePackResources.SharedZipFileAccess zipFileAccess, String prefix) @ L29

  • 构造器名:FilePackResources
  • 源码定位:L29
  • 修饰符:private

参数:

  • location: PackLocationInfo
  • zipFileAccess: FilePackResources.SharedZipFileAccess
  • prefix: String

说明:

TODO

方法

下面的方法块按源码顺序生成。

private static String getPathFromLocation(PackType type, Identifier location) @ L35

  • 方法名:getPathFromLocation
  • 源码定位:L35
  • 返回类型:String
  • 修饰符:private static

参数:

  • type: PackType
  • location: Identifier

说明:

TODO

public IoSupplier<InputStream> getRootResource(String... path) @ L39

  • 方法名:getRootResource
  • 源码定位:L39
  • 返回类型:IoSupplier
  • 修饰符:public

参数:

  • path: String…

说明:

TODO

public IoSupplier<InputStream> getResource(PackType type, Identifier location) @ L44

  • 方法名:getResource
  • 源码定位:L44
  • 返回类型:IoSupplier
  • 修饰符:public

参数:

  • type: PackType
  • location: Identifier

说明:

TODO

private String addPrefix(String path) @ L49

  • 方法名:addPrefix
  • 源码定位:L49
  • 返回类型:String
  • 修饰符:private

参数:

  • path: String

说明:

TODO

private IoSupplier<InputStream> getResource(String path) @ L53

  • 方法名:getResource
  • 源码定位:L53
  • 返回类型:IoSupplier
  • 修饰符:private

参数:

  • path: String

说明:

TODO

public Set<String> getNamespaces(PackType type) @ L63

  • 方法名:getNamespaces
  • 源码定位:L63
  • 返回类型:Set
  • 修饰符:public

参数:

  • type: PackType

说明:

TODO

public static String extractNamespace(String prefix, String name) @ L90

  • 方法名:extractNamespace
  • 源码定位:L90
  • 返回类型:String
  • 修饰符:public static

参数:

  • prefix: String
  • name: String

说明:

TODO

public void close() @ L101

  • 方法名:close
  • 源码定位:L101
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void listResources(PackType type, String namespace, String directory, PackResources.ResourceOutput output) @ L106

  • 方法名:listResources
  • 源码定位:L106
  • 返回类型:void
  • 修饰符:public

参数:

  • type: PackType
  • namespace: String
  • directory: String
  • output: PackResources.ResourceOutput

说明:

TODO

代码

public class FilePackResources extends AbstractPackResources {
    private static final Logger LOGGER = LogUtils.getLogger();
    private final FilePackResources.SharedZipFileAccess zipFileAccess;
    private final String prefix;
 
    private FilePackResources(PackLocationInfo location, FilePackResources.SharedZipFileAccess zipFileAccess, String prefix) {
        super(location);
        this.zipFileAccess = zipFileAccess;
        this.prefix = prefix;
    }
 
    private static String getPathFromLocation(PackType type, Identifier location) {
        return String.format(Locale.ROOT, "%s/%s/%s", type.getDirectory(), location.getNamespace(), location.getPath());
    }
 
    @Override
    public @Nullable IoSupplier<InputStream> getRootResource(String... path) {
        return this.getResource(String.join("/", path));
    }
 
    @Override
    public IoSupplier<InputStream> getResource(PackType type, Identifier location) {
        return this.getResource(getPathFromLocation(type, location));
    }
 
    private String addPrefix(String path) {
        return this.prefix.isEmpty() ? path : this.prefix + "/" + path;
    }
 
    private @Nullable IoSupplier<InputStream> getResource(String path) {
        ZipFile zipFile = this.zipFileAccess.getOrCreateZipFile();
        if (zipFile == null) {
            return null;
        } else {
            ZipEntry entry = zipFile.getEntry(this.addPrefix(path));
            return entry == null ? null : IoSupplier.create(zipFile, entry);
        }
    }
 
    @Override
    public Set<String> getNamespaces(PackType type) {
        ZipFile zipFile = this.zipFileAccess.getOrCreateZipFile();
        if (zipFile == null) {
            return Set.of();
        } else {
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            Set<String> namespaces = Sets.newHashSet();
            String typePrefix = this.addPrefix(type.getDirectory() + "/");
 
            while (entries.hasMoreElements()) {
                ZipEntry zipEntry = entries.nextElement();
                String name = zipEntry.getName();
                String namespace = extractNamespace(typePrefix, name);
                if (!namespace.isEmpty()) {
                    if (Identifier.isValidNamespace(namespace)) {
                        namespaces.add(namespace);
                    } else {
                        LOGGER.warn("Non {} character in namespace {} in pack {}, ignoring", "[a-z0-9_.-]", namespace, this.zipFileAccess.file);
                    }
                }
            }
 
            return namespaces;
        }
    }
 
    @VisibleForTesting
    public static String extractNamespace(String prefix, String name) {
        if (!name.startsWith(prefix)) {
            return "";
        } else {
            int prefixLength = prefix.length();
            int firstPart = name.indexOf(47, prefixLength);
            return firstPart == -1 ? name.substring(prefixLength) : name.substring(prefixLength, firstPart);
        }
    }
 
    @Override
    public void close() {
        this.zipFileAccess.close();
    }
 
    @Override
    public void listResources(PackType type, String namespace, String directory, PackResources.ResourceOutput output) {
        ZipFile zipFile = this.zipFileAccess.getOrCreateZipFile();
        if (zipFile != null) {
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            String root = this.addPrefix(type.getDirectory() + "/" + namespace + "/");
            String prefix = root + directory + "/";
 
            while (entries.hasMoreElements()) {
                ZipEntry zipEntry = entries.nextElement();
                if (!zipEntry.isDirectory()) {
                    String name = zipEntry.getName();
                    if (name.startsWith(prefix)) {
                        String path = name.substring(root.length());
                        Identifier id = Identifier.tryBuild(namespace, path);
                        if (id != null) {
                            output.accept(id, IoSupplier.create(zipFile, zipEntry));
                        } else {
                            LOGGER.warn("Invalid path in datapack: {}:{}, ignoring", namespace, path);
                        }
                    }
                }
            }
        }
    }
 
    public static class FileResourcesSupplier implements Pack.ResourcesSupplier {
        private final File content;
 
        public FileResourcesSupplier(Path content) {
            this(content.toFile());
        }
 
        public FileResourcesSupplier(File content) {
            this.content = content;
        }
 
        @Override
        public PackResources openPrimary(PackLocationInfo location) {
            FilePackResources.SharedZipFileAccess fileAccess = new FilePackResources.SharedZipFileAccess(this.content);
            return new FilePackResources(location, fileAccess, "");
        }
 
        @Override
        public PackResources openFull(PackLocationInfo location, Pack.Metadata metadata) {
            FilePackResources.SharedZipFileAccess fileAccess = new FilePackResources.SharedZipFileAccess(this.content);
            PackResources primary = new FilePackResources(location, fileAccess, "");
            List<String> overlays = metadata.overlays();
            if (overlays.isEmpty()) {
                return primary;
            } else {
                List<PackResources> overlayResources = new ArrayList<>(overlays.size());
 
                for (String overlay : overlays) {
                    overlayResources.add(new FilePackResources(location, fileAccess, overlay));
                }
 
                return new CompositePackResources(primary, overlayResources);
            }
        }
    }
 
    private static class SharedZipFileAccess implements AutoCloseable {
        private final File file;
        private @Nullable ZipFile zipFile;
        private boolean failedToLoad;
 
        private SharedZipFileAccess(File file) {
            this.file = file;
        }
 
        private @Nullable ZipFile getOrCreateZipFile() {
            if (this.failedToLoad) {
                return null;
            } else {
                if (this.zipFile == null) {
                    try {
                        this.zipFile = new ZipFile(this.file);
                    } catch (IOException var2) {
                        FilePackResources.LOGGER.error("Failed to open pack {}", this.file, var2);
                        this.failedToLoad = true;
                        return null;
                    }
                }
 
                return this.zipFile;
            }
        }
 
        @Override
        public void close() {
            if (this.zipFile != null) {
                IOUtils.closeQuietly(this.zipFile);
                this.zipFile = null;
            }
        }
 
        @Override
        protected void finalize() throws Throwable {
            this.close();
            super.finalize();
        }
    }
}

引用的其他类