PrefabSnapshotUtil class

Пакет: com.hypixel.hytale.builtin.adventure.worldevents.util

Файл: com/hypixel/hytale/builtin/adventure/worldevents/util/PrefabSnapshotUtil.java

Поля (35)

МодификаторыТипИмя
final String SNAPSHOT_DIRECTORY
return
Path var1
String var1
int var10
int var11
PrefabBuffer.Builder var12
BlockTypeAssetMap var13
PrefabUtil.PasteRegion.Column var16
PrefabBufferBlockEntry[] var17
int var18
Path var2
Path var2
Path var2
ObjectOpenHashSet var2
PrefabUtil.PasteRegion.Section var20
int var21
int var22
BlockType var23
UUID var24
Path var3
Path var3
String var3
Path var3
Path var3
PrefabBuffer var4
Path var4
Path var4
int var5
String var5
int var6
Path var6
int var7
int var8
int var9

Методы (12)

МодификаторыВозвратСигнатура
static void deleteSnapshotvoid deleteSnapshot(@Nonnull World var0, @Nonnull UUID var1)
for for(int var14 = var9; var14 <= var11; var14++)
for for(int var15 = var8; var15 <= var10; var15++)
for for(int var19 = 0; var18 <= var6; var19++)
for for(Path var4 : var2)
if if(var1 == null)
if if(var2 == null)
if if(var4 != null)
if if(var23 == null)
if if(var3 > 1)
static void saveWithRetryvoid saveWithRetry(@Nonnull Path var0, @Nonnull Path var1, @Nonnull PrefabBuffer var2, int var3)
static void writeSnapshotAsyncvoid writeSnapshotAsync(@Nonnull World var0, @Nonnull UUID var1, @Nonnull PrefabBuffer var2)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.adventure.worldevents.util;

class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.WorldEventManager;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.context.PrefabRemoveContext;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.logger.sentry.SkipSentryException;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.util.AssetPackPathUtil;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabRotation;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.PrefabBufferUtil;
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.prefab.selection.buffer.impl.PrefabBufferBlockEntry;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.util.PrefabUtil;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
class="kw">import java.io.IOException;
class="kw">import java.nio.file.DirectoryStream;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.util.Map;
class="kw">import java.util.UUID;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3ic;

class="kw">public class PrefabSnapshotUtil {
   class="kw">public class="kw">static class="kw">final String SNAPSHOT_DIRECTORY = "snapshots";
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">private class="kw">static class="kw">final int MAX_WRITE_ATTEMPTS = 3;
   class="kw">private class="kw">static class="kw">final long WRITE_RETRY_BACKOFF_MS = 250L;
   class="kw">private class="kw">static class="kw">final Map<Path, PrefabBuffer> PENDING_SNAPSHOTS = new ConcurrentHashMap<>();
   class="kw">private class="kw">static class="kw">final String[] MATCH_EXTENSIONS = new String[]{".prefab.json.lpf", ".lpf", ".prefab.json"};

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

   @Nullable
   class="kw">public class="kw">static IPrefabBuffer getAssetPrefabOrNull(@Nonnull Path var0) {
      Path var1 = resolveAssetPath(var0);
      if (var1 == null) {
         class="kw">return null;
      }

      Path var2 = resolveAssetReferencePath(var1);
      if (var2 == null) {
         class="kw">return null;
      }

      try {
         class="kw">return PrefabBufferUtil.getCached(var2);
      } catch (Throwable var4) {
         PrefabBufferUtil.removeCached(var2);
         ((HytaleLogger.Api)((HytaleLogger.Api)LOGGER.atWarning()).withCause(var4)).log("Failed to get prefab buffer with error");
         class="kw">return null;
      }
   }

   @Nullable
   class="kw">public class="kw">static IPrefabBuffer getSnapshotPrefabOrNull(@Nonnull World var0, @Nonnull UUID var1) {
      Path var2 = var0.getSavePath().resolve("snapshots");
      Path var3 = var2.resolve(var1.toString());
      PrefabBuffer var4 = PENDING_SNAPSHOTS.get(var3);
      if (var4 != null) {
         class="kw">return var4.newAccess();
      }

      try {
         class="kw">return PrefabBufferUtil.getCached(var3);
      } catch (Throwable var6) {
         class="kw">return null;
      }
   }

   @Nonnull
   class="kw">public class="kw">static UUID createSnapshot(
      @Nonnull World var0, @Nonnull PrefabUtil.PasteRegion var1, @Nonnull IPrefabBuffer var2, @Nonnull Vector3ic var3, @Nonnull PrefabRotation var4
   ) {
      assert var1.isFullyLoaded();
      int var5 = var3.y() + var2.getMinY();
      int var6 = var3.y() + var2.getMaxY();
      int var7 = 1 + var6 - var5;
      int var8 = var3.x() + var2.getMinX(var4);
      int var9 = var3.z() + var2.getMinZ(var4);
      int var10 = var3.x() + var2.getMaxX(var4);
      int var11 = var3.z() + var2.getMaxZ(var4);
      PrefabBuffer.Builder var12 = PrefabBuffer.newBuilder();
      BlockTypeAssetMap var13 = BlockType.getAssetMap();

      for (int var14 = var9; var14 <= var11; var14++) {
         for (int var15 = var8; var15 <= var10; var15++) {
            PrefabUtil.PasteRegion.Column var16 = var1.getColumnAtBlock(var15, var14);
            PrefabBufferBlockEntry[] var17 = new PrefabBufferBlockEntry[var7];
            int var18 = var5;

            for (int var19 = 0; var18 <= var6; var19++) {
               PrefabUtil.PasteRegion.Section var20 = var1.getSectionAtBlock(var15, var18, var14);
               int var21 = ChunkUtil.indexBlock(var15, var18, var14);
               int var22 = var20.getBlock(var21);
               BlockType var23 = var13.getAsset(var22);
               if (var23 == null) {
                  var17[var19] = new PrefabBufferBlockEntry(var18 - var3.y(), 0, "Empty");
               } else {
                  var17[var19] = new PrefabBufferBlockEntry(
                     var18 - var3.y(),
                     var22,
                     var23.getId(),
                     1.0F,
                     var20.getState(var21),
                     var20.getFluid(var21),
                     var20.getFluidLevel(var21),
                     var20.getSupport(var21),
                     var20.getRotation(var21),
                     var20.getFiller(var21)
                  );
               }

               var18++;
            }

            var12.addColumn(var15 - var3.x(), var14 - var3.z(), var17, null);
         }
      }

      UUID var24 = UUID.randomUUID();
      writeSnapshotAsync(var0, var24, var12.build());
      class="kw">return var24;
   }

   class="kw">public class="kw">static void deleteSnapshot(@Nonnull World var0, @Nonnull UUID var1) {
      Path var2 = var0.getSavePath().resolve("snapshots");
      Path var3 = var2.resolve(var1.toString());
      PENDING_SNAPSHOTS.remove(var3);
      Path var4 = resolveSnapshotPath(var2, var1);
      CompletableFuture.completedFuture(var4).thenAcceptAsync(var1x -> {
         try {
            Files.deleteIfExists(var1x);
         } catch (IOException var6) {
            ((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(new SkipSentryException(var6))).log("Failed to delete world event snapshot %s", var1x);
         } class="kw">finally {
            PrefabBufferUtil.removeCached(var3);
         }
      });
   }

   @Nonnull
   class="kw">public class="kw">static CompletableFuture<Void> cleanSnapshotsDir(@Nonnull World var0, @Nonnull WorldEventManager var1) {
      ObjectOpenHashSet var2 = new ObjectOpenHashSet();
      var1.forEach(var2, (var0x, var1x) -> var0x.context.forEach(PrefabRemoveContext.class, var1x, null, (var0xx, var1xx, var2x) -> {
         String var3 = var0xx.snapshot().toString();
         var1xx.add(var3);
      }));
      Path var3 = var0.getSavePath().resolve("snapshots");
      class="kw">return CompletableFuture.runAsync(() -> {
         if (Files.exists(var3)) {
            try (DirectoryStream var2 = Files.newDirectoryStream(var3)) {
               for (Path var4 : var2) {
                  String var5 = var4.getFileName().toString().replace(".lpf", "");
                  if (!var2.contains(var5)) {
                     Path var6 = var4.resolveSibling(var5);
                     PENDING_SNAPSHOTS.remove(var6);
                     PrefabBufferUtil.removeCached(var6);

                     try {
                        Files.deleteIfExists(var4);
                     } catch (IOException var9) {
                        ((HytaleLogger.Api)((HytaleLogger.Api)LOGGER.atWarning()).withCause(var9)).log("Failed to remove snapshot prefab: %s", var4);
                     }
                  }
               }
            } catch (IOException var11) {
               ((HytaleLogger.Api)((HytaleLogger.Api)LOGGER.atWarning()).withCause(var11)).log("An error occurred whilst cleaning snapshots in: %s", var3);
            }
         }
      });
   }

   @Nullable
   class="kw">public class="kw">static Path resolveAssetPath(@Nonnull Path var0) {
      if (var0.isAbsolute()) {
         class="kw">return AssetPackPathUtil.relativizeAssetPath(var0) == null ? null : var0;
      } else {
         class="kw">return AssetPackPathUtil.resolveAssetPath(var0, MATCH_EXTENSIONS);
      }
   }

   @Nonnull
   class="kw">public class="kw">static Path resolveSnapshotPath(@Nonnull Path var0, @Nonnull UUID var1) {
      class="kw">return var0.resolve(var1 + ".lpf");
   }

   @Nullable
   class="kw">public class="kw">static Path resolveAssetReferencePath(@Nonnull Path var0) {
      if (var0.getFileName() == null) {
         class="kw">return null;
      } else {
         String var1 = var0.getFileName().toString();
         if (var1.endsWith(".prefab.json.lpf")) {
            class="kw">return var0.resolveSibling(var1.substring(0, var1.length() - ".prefab.json.lpf".length()));
         } else if (var1.endsWith(".prefab.json")) {
            class="kw">return var0.resolveSibling(var1.substring(0, var1.length() - ".prefab.json".length()));
         } else {
            class="kw">return var1.endsWith(".lpf") ? var0.resolveSibling(var1.substring(0, var1.length() - ".lpf".length())) : var0;
         }
      }
   }

   class="kw">protected class="kw">static void writeSnapshotAsync(@Nonnull World var0, @Nonnull UUID var1, @Nonnull PrefabBuffer var2) {
      Path var3 = var0.getSavePath().resolve("snapshots");
      Path var4 = var3.resolve(var1.toString());
      PENDING_SNAPSHOTS.put(var4, var2);

      try {
         Files.createDirectories(var3);
      } catch (IOException var6) {
         ((HytaleLogger.Api)((HytaleLogger.Api)LOGGER.atWarning()).withCause(new SkipSentryException(var6)))
            .log("Failed to create world event snapshot directory %s", var3);
         class="kw">return;
      }

      saveWithRetry(resolveSnapshotPath(var3, var1), var4, var2, 3);
   }

   class="kw">private class="kw">static void saveWithRetry(@Nonnull Path var0, @Nonnull Path var1, @Nonnull PrefabBuffer var2, int var3) {
      PrefabBufferUtil.writeToFileAsync(var2, var0)
         .thenRun(() -> PENDING_SNAPSHOTS.remove(var1))
         .exceptionally(
            var4 -> {
               if (var3 > 1) {
                  CompletableFuture.delayedExecutor(250L, TimeUnit.MILLISECONDS).execute(() -> saveWithRetry(var0, var1, var2, var3 - 1));
               } else {
                  ((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(var4))
                     .log("Failed to write world event snapshot %s, keeping it in memory for this session", var0);
               }

               class="kw">return null;
            }
         );
   }
}