content: package org.allaymc.server.pack.loader;
  
  import lombok.SneakyThrows;
  import org.allaymc.api.pack.PackLoader;
  import org.allaymc.server.pack.PackUtils;
  import org.allaymc.server.pack.ResourcePackException;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URI;
  import java.nio.file.FileSystem;
  import java.nio.file.FileSystems;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.util.Collections;
  
  /**
   * The loader that loads packs from zip/mcpack files using java.nio.file.FileSystem.
   */
  public class ZipPackLoader implements PackLoader {
  
      public static final PackLoader.Factory FACTORY = new ZipFactory();
  
      private final Path path;
      private final FileSystem zipFileSystem;
      private final Path root;
  
      @SneakyThrows
      private ZipPackLoader(Path path) {
          this.path = path;
          this.zipFileSystem = FileSystems.newFileSystem(URI.create("jar:" + path.toUri()), Collections.singletonMap("create", "false"));
          this.root = zipFileSystem.getPath("/");
      }
  
      @Override
      public Path getLocation() {
          return this.path;
      }
  
      @Override
      public boolean hasFile(String name) {
          Path zipPath = root.resolve(name);
          return Files.exists(zipPath) && Files.isRegularFile(zipPath);
      }
  
      @Override
      public InputStream getFile(String name) throws IOException {
          Path zipPath = root.resolve(name);
          return Files.exists(zipPath) ? Files.newInputStream(zipPath) : null;
      }
  
      @Override
      public byte[] readAllBytes() {
          try {
              return Files.readAllBytes(this.path);
          } catch (IOException e) {
              throw new ResourcePackException(e);
          }
      }
  
      @Override
      public String getContentKey() {
          var keyFilePath = path.getParent().resolve(path.getFileName() + ".key");
          try {
              return Files.exists(keyFilePath) ? Files.readString(keyFilePath) : "";
          } catch (IOException e) {
              throw new ResourcePackException(e);
          }
      }
  
      @Override
      public void close() throws IOException {
          this.zipFileSystem.close();
      }
  
      private static class ZipFactory implements Factory {
          @Override
          public boolean canLoad(Path path) {
              return PackUtils.isZipPack(path);
          }
  
          @Override
          public PackLoader create(Path path) {
              return new ZipPackLoader(path);
          }
      }
  }
  