PrefabBufferUtil class

Пакет: com.hypixel.hytale.server.core.prefab.selection.buffer

Файл: com/hypixel/hytale/server/core/prefab/selection/buffer/PrefabBufferUtil.java

Поля (35)

МодификаторыТипИмя
final Path CACHE_PATH
private PrefabBuffer buffer
private final StampedLock lock
WeakReference var1
String var1
byte[] var1
PrefabBufferUtil.CachedEntry[] var1
Path var11
long var15
PrefabBufferUtil.CachedEntry var2
var2
String var2
var2
Path var2
long var3
String var3
PrefabBufferUtil.CachedEntry var3
Path var4
BasicFileAttributes var4
var4
Path var5
var5
var5
var5
var5
FileTime var5
var5
var5
AssetPack var6
var6
var6
PrefabBuffer var6
Path var7
Path var7
String var8

Методы (14)

МодификаторыВозвратСигнатура
private CachedEntryprivate CachedEntry()
if if(var2 != null)
if if(var2.buffer != null)
if if(var2.buffer != null)
if if(var6 != null)
if if(var2 != null)
if if(var3 != null)
abstract return loadFromJsonreturn loadFromJson(var6, var0, var5, var11)
abstract return loadFromLPFreturn loadFromLPF(var0, var4)
abstract return loadFromLPFreturn loadFromLPF(var0, var7)
static PrefabBuffer readFromFilePrefabBuffer readFromFile(@Nonnull Path var0)
abstract return readFromFilereturn readFromFile(var1)
abstract return readFromFilereturn readFromFile(var2)
static void removeCachedvoid removeCached(@Nonnull Path var0)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.prefab.selection.buffer;

class="kw">import com.hypixel.hytale.assetstore.AssetPack;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.logger.sentry.SkipSentryException;
class="kw">import com.hypixel.hytale.server.core.Options;
class="kw">import com.hypixel.hytale.server.core.asset.AssetModule;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.IPrefabBuffer;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.PrefabBuffer;
class="kw">import com.hypixel.hytale.server.core.util.BsonUtil;
class="kw">import com.hypixel.hytale.server.core.util.io.FileUtil;
class="kw">import com.hypixel.hytale.sneakythrow.SneakyThrow;
class="kw">import java.io.BufferedOutputStream;
class="kw">import java.io.DataOutputStream;
class="kw">import java.io.IOException;
class="kw">import java.lang.ref.WeakReference;
class="kw">import java.nio.ByteBuffer;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.nio.file.attribute.BasicFileAttributes;
class="kw">import java.nio.file.attribute.FileTime;
class="kw">import java.util.Map;
class="kw">import java.util.Set;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.CompletionException;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.locks.StampedLock;
class="kw">import java.util.logging.Level;
class="kw">import java.util.regex.Pattern;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class PrefabBufferUtil {
   class="kw">public class="kw">static class="kw">final Path CACHE_PATH = Options.getOrDefault(Options.PREFAB_CACHE_DIRECTORY, Options.getOptionSet(), Path.of(".cache/prefabs"));
   class="kw">public class="kw">static class="kw">final String LPF_FILE_SUFFIX = ".lpf";
   class="kw">public class="kw">static class="kw">final String JSON_FILE_SUFFIX = ".prefab.json";
   class="kw">public class="kw">static class="kw">final String JSON_LPF_FILE_SUFFIX = ".prefab.json.lpf";
   class="kw">public class="kw">static class="kw">final String FILE_SUFFIX_REGEX = "((?<!\\.prefab\\.json)\\.lpf|\\.prefab\\.json)$";
   class="kw">public class="kw">static class="kw">final Pattern FILE_SUFFIX_PATTERN = Pattern.compile("((?<!\\.prefab\\.json)\\.lpf|\\.prefab\\.json)$");
   class="kw">public class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">private class="kw">static class="kw">final Map<Path, WeakReference<PrefabBufferUtil.CachedEntry>> CACHE = new ConcurrentHashMap<>();
   class="kw">private class="kw">static class="kw">final Set<Path> SAVING_PREFABS = ConcurrentHashMap.newKeySet();

   class="kw">public PrefabBufferUtil() {
   }

   @Nonnull
   class="kw">public class="kw">static IPrefabBuffer getCached(@Nonnull Path var0) {
      WeakReference var1 = CACHE.get(var0);
      PrefabBufferUtil.CachedEntry var2 = var1 != null ? var1.get() : null;
      if (var2 != null) {
         long var3 = var2.lock.readLock();

         try {
            if (var2.buffer != null) {
               class="kw">return var2.buffer.newAccess();
            }
         } class="kw">finally {
            var2.lock.unlockRead(var3);
         }
      }

      var2 = getOrCreateCacheEntry(var0);
      long var15 = var2.lock.writeLock();

      try {
         if (var2.buffer != null) {
            class="kw">return var2.buffer.newAccess();
         }

         var2.buffer = loadBuffer(var0);
         class="kw">return var2.buffer.newAccess();
      } class="kw">finally {
         var2.lock.unlockWrite(var15);
      }
   }

   class="kw">public class="kw">static void removeCached(@Nonnull Path var0) {
      CACHE.remove(var0);
   }

   @Nonnull
   class="kw">public class="kw">static PrefabBuffer loadBuffer(@Nonnull Path var0) {
      String var1 = var0.getFileName().toString();
      String var2 = var1.replace(".prefab.json.lpf", "").replace(".prefab.json", "");
      if (var2.endsWith(".lpf")) {
         var2 = var2.substring(0, var2.length() - ".lpf".length());
      }

      String var3 = var2;
      Path var4 = var0.resolveSibling(var3 + ".lpf");
      if (Files.exists(var4)) {
         class="kw">return loadFromLPF(var0, var4);
      }

      Path var5;
      AssetPack var6;
      if (AssetModule.get().isAssetPathImmutable(var0)) {
         Path var7 = var0.resolveSibling(var3 + ".prefab.json.lpf");
         if (Files.exists(var7)) {
            class="kw">return loadFromLPF(var0, var7);
         }

         var6 = AssetModule.get().findAssetPackForPath(var0);
         if (var6 != null) {
            String var8 = FileUtil.INVALID_FILENAME_CHARACTERS.matcher(var6.getName()).replaceAll("_");
            var5 = CACHE_PATH.resolve(var8).resolve(var6.getRoot().relativize(var7).toString());
         } else if (var7.getRoot() != null) {
            var5 = CACHE_PATH.resolve(var7.subpath(1, var7.getNameCount()).toString());
         } else {
            var5 = CACHE_PATH.resolve(var7.toString());
         }
      } else {
         var5 = var0.resolveSibling(var3 + ".prefab.json.lpf");
         var6 = null;
      }

      Path var11 = var0.resolveSibling(var3 + ".prefab.json");
      if (!Files.exists(var11)) {
         try {
            Files.deleteIfExists(var5);
         } catch (IOException var9) {
         }

         throw new Error("Error loading Prefab from " + var11.toAbsolutePath() + " (.lpf and .prefab.json) File NOT found!");
      } else {
         try {
            class="kw">return loadFromJson(var6, var0, var5, var11);
         } catch (IOException var10) {
            throw SneakyThrow.sneakyThrow(var10);
         }
      }
   }

   @Nonnull
   class="kw">public class="kw">static CompletableFuture<Void> writeToFileAsync(@Nonnull PrefabBuffer var0, @Nonnull Path var1) {
      class="kw">return CompletableFuture.runAsync(SneakyThrow.sneakyRunnable(() -> {
         Path var2 = var1.resolveSibling(var1.getFileName() + ".tmp");

         try (DataOutputStream var3 = new DataOutputStream(new BufferedOutputStream(Files.newOutputStream(var2)))) {
            BinaryPrefabBufferCodec.INSTANCE.serialize(var0, var3);
         }

         FileUtil.atomicMove(var2, var1);
      }));
   }

   class="kw">public class="kw">static PrefabBuffer readFromFile(@Nonnull Path var0) {
      class="kw">return readFromFileAsync(var0).join();
   }

   @Nonnull
   class="kw">public class="kw">static CompletableFuture<PrefabBuffer> readFromFileAsync(@Nonnull Path var0) {
      class="kw">return CompletableFuture.supplyAsync(SneakyThrow.sneakySupplier(() -> {
         byte[] var1 = Files.readAllBytes(var0);
         class="kw">return BinaryPrefabBufferCodec.INSTANCE.deserialize(ByteBuffer.wrap(var1));
      }));
   }

   @Nonnull
   class="kw">public class="kw">static PrefabBuffer loadFromLPF(@Nonnull Path var0, @Nonnull Path var1) {
      try {
         class="kw">return readFromFile(var1);
      } catch (Exception var3) {
         throw new Error("Error while loading prefab " + var0.toAbsolutePath() + " from " + var1.toAbsolutePath(), var3);
      }
   }

   @Nonnull
   class="kw">public class="kw">static PrefabBuffer loadFromJson(@Nullable AssetPack var0, Path var1, @Nonnull Path var2, @Nonnull Path var3) class="kw">throws IOException {
      BasicFileAttributes var4 = null;

      try {
         var4 = Files.readAttributes(var2, BasicFileAttributes.class);
      } catch (IOException var12) {
      }

      FileTime var5;
      if (var0 != null && var0.isImmutable()) {
         var5 = Files.readAttributes(var0.getPackLocation(), BasicFileAttributes.class).lastModifiedTime();
      } else {
         var5 = Files.readAttributes(var3, BasicFileAttributes.class).lastModifiedTime();
      }

      if (var4 != null && var5.compareTo(var4.lastModifiedTime()) <= 0) {
         try {
            class="kw">return readFromFile(var2);
         } catch (CompletionException var13) {
            if (!Options.getOptionSet().has(Options.VALIDATE_PREFABS)) {
               if (var13.getCause() class="kw">instanceof UpdateBinaryPrefabException) {
                  LOGGER.at(Level.FINE).log("Ignoring LPF %s due to: %s", var1, var13.getMessage());
               } else {
                  ((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(new SkipSentryException(var13))).log("Failed to load %s", var2);
               }
            }
         }
      }

      try {
         PrefabBuffer var6 = BsonPrefabBufferDeserializer.INSTANCE.deserialize(var3, BsonUtil.readDocument(var3, false).join());
         Path var7 = var1.normalize();
         if (!Options.getOptionSet().has(Options.DISABLE_CPB_BUILD) && SAVING_PREFABS.add(var7)) {
            try {
               Files.createDirectories(var2.getParent());
               writeToFileAsync(var6, var2)
                  .thenRun(() -> {
                     try {
                        Files.setLastModifiedTime(var2, var5);
                     } catch (IOException var3x) {
                     }
                  })
                  .exceptionally(
                     var1x -> {
                        ((HytaleLogger.Api)HytaleLogger.getLogger().at(Level.FINE).withCause(new SkipSentryException(var1x)))
                           .log("Failed to save prefab cache %s", var2);
                        class="kw">return null;
                     }
                  )
                  .whenComplete((var1x, var2x) -> SAVING_PREFABS.remove(var7));
            } catch (IOException var9) {
               LOGGER.at(Level.FINE).log("Cannot create cache directory for %s: %s", var2, var9.getMessage());
               SAVING_PREFABS.remove(var7);
            } catch (Throwable var10) {
               SAVING_PREFABS.remove(var7);
               throw var10;
            }
         }

         class="kw">return var6;
      } catch (Exception var11) {
         throw new Error("Error while loading Prefab from " + var3.toAbsolutePath(), var11);
      }
   }

   @Nonnull
   class="kw">private class="kw">static PrefabBufferUtil.CachedEntry getOrCreateCacheEntry(Path var0) {
      PrefabBufferUtil.CachedEntry[] var1 = new PrefabBufferUtil.CachedEntry[1];
      CACHE.compute(var0, (var1x, var2) -> {
         if (var2 != null) {
            PrefabBufferUtil.CachedEntry var3 = var2.get();
            var1[0] = var3;
            if (var3 != null) {
               class="kw">return var2;
            }
         }

         class="kw">return new WeakReference<>(var1[0] = new PrefabBufferUtil.CachedEntry());
      });
      class="kw">return var1[0];
   }

   class="kw">private class="kw">static class CachedEntry {
      class="kw">private class="kw">final StampedLock lock = new StampedLock();
      class="kw">private PrefabBuffer buffer;

      class="kw">private CachedEntry() {
      }
   }
}