ConvertPrefabsCommand class

Пакет: com.hypixel.hytale.server.core.command.commands.utility

Файл: com/hypixel/hytale/server/core/command/commands/utility/ConvertPrefabsCommand.java

extends: AbstractAsyncCommand

Поля (33)

МодификаторыТипИмя
final String UNABLE_TO_LOAD_MODEL
List var10
CompletableFuture var10
var10
var10
Path var11
Universe var11
CompletableFuture var11
var11
var11
String var12
WorldConfig var12
int var13
List var14
Path var15
int var15
Path var16
CompletableFuture[] var16
Path var17
Path var18
List var19
boolean var2
boolean[] var2
boolean var3
boolean var4
String var4
boolean var5
Message var5
UnknownComponents var5
boolean var6
boolean var7
World var8
List var9

Методы (14)

МодификаторыВозвратСигнатура
abstract for for(int var12 = 0; var12 < var1.size()
if if(var8 == null)
if if(!var5 && !var2)
if if(var10 != null)
if if(var10 != null)
if if(var15 > 0)
if if(var3)
if if(var7)
if if(!var2[0])
if if(var4 != null)
static boolean isBinaryboolean isBinary(@Nonnull Path var0)
private void sendCompletionMessagesvoid sendCompletionMessages(@Nonnull CommandContext var1, @Nonnull Path var2, @Nonnull List<String> var3, @Nonnull List<String> var4)
abstract super super("convertprefabs", "server.commands.convertprefabs.desc")
return switchreturn switch(var12)

Исходный код

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

class="kw">import com.hypixel.hytale.common.util.PathUtil;
class="kw">import com.hypixel.hytale.component.data.unknown.UnknownComponents;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.command.system.CommandContext;
class="kw">import com.hypixel.hytale.server.core.command.system.arguments.system.DefaultArg;
class="kw">import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
class="kw">import com.hypixel.hytale.server.core.command.system.arguments.system.OptionalArg;
class="kw">import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes;
class="kw">import com.hypixel.hytale.server.core.command.system.basecommands.AbstractAsyncCommand;
class="kw">import com.hypixel.hytale.server.core.prefab.PrefabStore;
class="kw">import com.hypixel.hytale.server.core.prefab.config.SelectionPrefabSerializer;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.PrefabBufferSelectionConverter;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.buffer.PrefabBufferUtil;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.WorldConfig;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.provider.EmptyChunkStorageProvider;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.resources.EmptyResourceStorageProvider;
class="kw">import com.hypixel.hytale.server.core.universe.world.worldgen.provider.DummyWorldGenProvider;
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.server.core.util.message.MessageFormat;
class="kw">import com.hypixel.hytale.sneakythrow.SneakyThrow;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import java.io.IOException;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.nio.file.Paths;
class="kw">import java.util.List;
class="kw">import java.util.UUID;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.stream.Collectors;
class="kw">import java.util.stream.Stream;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class ConvertPrefabsCommand class="kw">extends AbstractAsyncCommand {
   class="kw">private class="kw">static class="kw">final String UNABLE_TO_LOAD_MODEL = "Unable to load entity with model ";
   class="kw">private class="kw">static class="kw">final String FAILED_TO_FIND_BLOCK = "Failed to find block ";
   class="kw">private class="kw">static class="kw">final int BATCH_SIZE = 10;
   class="kw">private class="kw">static class="kw">final long DELAY_BETWEEN_BATCHES_MS = 50L;
   @Nonnull
   class="kw">private class="kw">static class="kw">final Message MESSAGE_COMMANDS_CONVERT_PREFABS_FAILED = Message.translation("server.commands.convertprefabs.failed");
   @Nonnull
   class="kw">private class="kw">static class="kw">final Message MESSAGE_COMMANDS_CONVERT_PREFABS_DEFAULT_WORLD_NULL = Message.translation("server.commands.convertprefabs.defaultWorldNull");
   @Nonnull
   class="kw">private class="kw">final FlagArg blocksFlag = this.withFlagArg("blocks", "server.commands.convertprefabs.blocks.desc");
   @Nonnull
   class="kw">private class="kw">final FlagArg fillerFlag = this.withFlagArg("filler", "server.commands.convertprefabs.filler.desc");
   @Nonnull
   class="kw">private class="kw">final FlagArg relativeFlag = this.withFlagArg("relative", "server.commands.convertprefabs.relative.desc");
   @Nonnull
   class="kw">private class="kw">final FlagArg entitiesFlag = this.withFlagArg("entities", "server.commands.convertprefabs.entities.desc");
   class="kw">private class="kw">final FlagArg destructiveFlag = this.withFlagArg("destructive", "server.commands.convertprefabs.destructive.desc");
   class="kw">private class="kw">final FlagArg onlyUnknownFlag = this.withFlagArg("only-unknown", "server.commands.convertprefabs.onlyUnknown.desc");
   @Nonnull
   class="kw">private class="kw">final OptionalArg<String> pathArg = this.withOptionalArg("path", "server.commands.convertprefabs.path.desc", ArgTypes.STRING);
   @Nonnull
   class="kw">private class="kw">final DefaultArg<String> storeArg = this.withDefaultArg(
      "store", "server.commands.convertprefabs.store.desc", ArgTypes.STRING, "asset", "server.commands.convertprefabs.store.defaultDesc"
   );

   class="kw">public ConvertPrefabsCommand() {
      super("convertprefabs", "server.commands.convertprefabs.desc");
   }

   @Nonnull
   @Override
   class="kw">protected CompletableFuture<Void> executeAsync(@Nonnull CommandContext var1) {
      boolean var2 = this.blocksFlag.get(var1);
      boolean var3 = this.fillerFlag.get(var1);
      boolean var4 = this.relativeFlag.get(var1);
      boolean var5 = this.entitiesFlag.get(var1);
      boolean var6 = this.destructiveFlag.get(var1);
      boolean var7 = this.onlyUnknownFlag.get(var1);
      World var8 = Universe.get().getDefaultWorld();
      if (var8 == null) {
         var1.sendMessage(MESSAGE_COMMANDS_CONVERT_PREFABS_DEFAULT_WORLD_NULL);
         class="kw">return CompletableFuture.completedFuture(null);
      }

      var8.getChunk(ChunkUtil.indexChunk(0, 0));
      List var9 = new ObjectArrayList();
      List var10 = new ObjectArrayList();
      String var12 = this.storeArg.get(var1);
      if (this.pathArg.provided(var1)) {
         Path var18 = Paths.get(this.pathArg.get(var1));
         if (!PathUtil.isInTrustedRoot(var18)) {
            var1.sendMessage(Message.translation("server.commands.convertprefabs.invalidPath"));
            class="kw">return CompletableFuture.completedFuture(null);
         } else {
            class="kw">return this.convertPath(var18, var2, var3, var4, var5, var6, var7, var9, var10).thenApply(var5x -> {
               this.sendCompletionMessages(var1, var18, var9, var10);
               class="kw">return null;
            });
         }
      } else {
         class="kw">return class="kw">switch (var12) {
            case "server" -> {
               Path var17 = PrefabStore.get().getServerPrefabsPath();
               yield this.convertPath(var17, var2, var3, var4, var5, var6, var7, var9, var10).thenApply(var5x -> {
                  this.sendCompletionMessages(var1, var17, var9, var10);
                  class="kw">return null;
               });
            }
            case "asset" -> {
               Path var16 = PrefabStore.get().getAssetPrefabsPath();
               yield this.convertPath(var16, var2, var3, var4, var5, var6, var7, var9, var10).thenApply(var5x -> {
                  this.sendCompletionMessages(var1, var16, var9, var10);
                  class="kw">return null;
               });
            }
            case "worldgen" -> {
               Path var15 = PrefabStore.get().getWorldGenPrefabsPath();
               yield this.convertPath(var15, var2, var3, var4, var5, var6, var7, var9, var10).thenApply(var5x -> {
                  this.sendCompletionMessages(var1, var15, var9, var10);
                  class="kw">return null;
               });
            }
            case "all" -> {
               Path var11 = Path.of("");
               yield this.convertPath(PrefabStore.get().getWorldGenPrefabsPath(), var2, var3, var4, var5, var6, var7, var9, var10)
                  .thenCompose(var9x -> this.convertPath(PrefabStore.get().getServerPrefabsPath(), var2, var3, var4, var5, var6, var7, var9, var10))
                  .thenCompose(var9x -> this.convertPath(PrefabStore.get().getAssetPrefabsPath(), var2, var3, var4, var5, var6, var7, var9, var10))
                  .thenApply(var5x -> {
                     this.sendCompletionMessages(var1, var11, var9, var10);
                     class="kw">return null;
                  });
            }
            class="kw">default -> {
               var1.sendMessage(Message.translation("server.commands.convertprefabs.invalidStore").param("store", var12));
               yield CompletableFuture.completedFuture(null);
            }
         };
      }
   }

   class="kw">private void sendCompletionMessages(@Nonnull CommandContext var1, @Nonnull Path var2, @Nonnull List<String> var3, @Nonnull List<String> var4) {
      if (!var4.isEmpty()) {
         Message var5 = Message.translation("server.commands.convertprefabs.skipped");
         var1.sendMessage(MessageFormat.list(var5, var4.stream().map(Message::raw).collect(Collectors.toSet())));
      }

      if (!var3.isEmpty()) {
         var1.sendMessage(MessageFormat.list(MESSAGE_COMMANDS_CONVERT_PREFABS_FAILED, var3.stream().map(Message::raw).collect(Collectors.toSet())));
      }

      var1.sendMessage(Message.translation("server.commands.prefabConvertionDone").param("path", var2.toString()));
   }

   @Nonnull
   class="kw">private CompletableFuture<Void> convertPath(
      @Nonnull Path var1,
      boolean var2,
      boolean var3,
      boolean var4,
      boolean var5,
      boolean var6,
      boolean var7,
      @Nonnull List<String> var8,
      @Nonnull List<String> var9
   ) {
      if (!Files.exists(var1)) {
         class="kw">return CompletableFuture.completedFuture(null);
      }

      CompletableFuture var10;
      if (!var5 && !var2) {
         var10 = null;
      } else {
         Universe var11 = Universe.get();
         WorldConfig var12 = new WorldConfig();
         var12.setWorldGenProvider(new DummyWorldGenProvider());
         var12.setChunkStorageProvider(EmptyChunkStorageProvider.INSTANCE);
         var12.setResourceStorageProvider(EmptyResourceStorageProvider.INSTANCE);

         try {
            var10 = var11.makeWorld("ConvertPrefabs-" + UUID.randomUUID(), Files.createTempDirectory("convertprefab"), var12);
         } catch (IOException var15) {
            throw SneakyThrow.sneakyThrow(var15);
         }
      }

      try (Stream var18 = Files.walk(var1, FileUtil.DEFAULT_WALK_TREE_OPTIONS_ARRAY)) {
         List var19 = var18.filter(var0 -> Files.isRegularFile(var0) && PrefabStore.PREFAB_FILTER.test(var0)).collect(Collectors.toList());
         if (var19.isEmpty()) {
            if (var10 != null) {
               var10.thenAccept(var0 -> Universe.get().removeWorld(var0.getName()));
            }

            class="kw">return CompletableFuture.completedFuture(null);
         } else {
            class="kw">return this.processPrefabsInBatches(var19, var2, var3, var4, var5, var6, var7, var10, var8, var9).thenApply(var1x -> {
               if (var10 != null) {
                  var10.thenAccept(var0x -> Universe.get().removeWorld(var0x.getName()));
               }

               class="kw">return null;
            });
         }
      } catch (IOException var17) {
         throw SneakyThrow.sneakyThrow(var17);
      }
   }

   @Nonnull
   class="kw">private CompletableFuture<Void> processPrefabsInBatches(
      @Nonnull List<Path> var1,
      boolean var2,
      boolean var3,
      boolean var4,
      boolean var5,
      boolean var6,
      boolean var7,
      @Nullable CompletableFuture<World> var8,
      @Nonnull List<String> var9,
      @Nonnull List<String> var10
   ) {
      CompletableFuture var11 = CompletableFuture.completedFuture(null);

      for (int var12 = 0; var12 < var1.size(); var12 += 10) {
         int var13 = Math.min(var12 + 10, var1.size());
         List var14 = var1.subList(var12, var13);
         int var15 = var12 / 10;
         if (var15 > 0) {
            var11 = var11.thenCompose(var0 -> CompletableFuture.runAsync(() -> {}, CompletableFuture.delayedExecutor(50L, TimeUnit.MILLISECONDS)));
         }

         CompletableFuture[] var16 = var14.stream()
            .map(var10x -> this.processPrefab(var10x, var2, var3, var4, var5, var6, var7, var8, var9, var10))
            .toArray(CompletableFuture[]::new);
         var11 = var11.thenCompose(var1x -> CompletableFuture.allOf(var16));
      }

      class="kw">return var11;
   }

   @Nonnull
   class="kw">private CompletableFuture<Void> processPrefab(
      @Nonnull Path var1,
      boolean var2,
      boolean var3,
      boolean var4,
      boolean var5,
      boolean var6,
      boolean var7,
      @Nullable CompletableFuture<World> var8,
      @Nonnull List<String> var9,
      @Nonnull List<String> var10
   ) {
      class="kw">return readPrefab(var1)
         .thenApply(var3x -> {
            if (var3) {
               var3x.tryFixFiller(var6);
            }

            class="kw">return var4 ? var3x.relativize() : var3x;
         })
         .thenApply(var1x -> {
            if (var7) {
               boolean[] var2 = new boolean[1];
               var1x.forEachBlock((var1xx, var2x, var3x, var4x) -> {
                  if (var4x.holder() != null) {
                     UnknownComponents var5 = var4x.holder().getComponent(ChunkStore.REGISTRY.getUnknownComponentType());
                     if (var5 != null && !var5.getUnknownComponents().isEmpty()) {
                        var2[0] = true;
                     }
                  }
               });
               if (!var2[0]) {
                  class="kw">return null;
               }
            }

            class="kw">return (BlockSelection)var1x;
         })
         .thenCompose(var3x -> var3x != null && var5 && var8 != null ? var8.<Void>thenCompose(var2x -> CompletableFuture.runAsync(() -> {
            try {
               var3x.reserializeEntities(var2x.getEntityStore().getStore(), var6);
            } catch (IOException var4) {
               throw SneakyThrow.sneakyThrow(var4);
            }
         }, var2x)).thenApply(var1x -> var3x) : CompletableFuture.completedFuture(var3x))
         .thenCompose(
            var3x -> var3x != null && var2 && var8 != null
               ? var8.<Void>thenCompose(var2x -> CompletableFuture.runAsync(() -> var3x.reserializeBlockStates(var2x.getChunkStore(), var6), var2x))
                  .thenApply(var1x -> var3x)
               : CompletableFuture.completedFuture(var3x)
         )
         .thenCompose(var1x -> var1x == null ? CompletableFuture.completedFuture(null) : writePrefab(var1, var1x))
         .exceptionally(
            var3x -> {
               String var4 = var3x.getCause() != null ? var3x.getCause().getMessage() : null;
               if (var4 != null) {
                  if (var4.contains("Failed to find block ")) {
                     if (var4.substring("Failed to find block ".length()).contains("%")) {
                        var10.add("Skipped prefab " + var1 + " because it contains block % chance.");
                        class="kw">return null;
                     }

                     var9.add("Failed to update " + var1 + " because " + var4);
                     class="kw">return null;
                  }

                  if (var4.contains("Unable to load entity with model ")) {
                     var9.add("Failed to update " + var1 + " because " + var4);
                     class="kw">return null;
                  }
               }

               var9.add(
                  "Failed to update "
                     + var1
                     + " because "
                     + (var4 != null ? var4 : (var3x.getCause() != null ? var3x.getCause().getClass() : var3x.getClass()))
               );
               if (var3x.getCause() != null) {
                  new Exception("Failed to update " + var1, var3x.getCause()).printStackTrace();
               }

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

   @Nonnull
   class="kw">private class="kw">static CompletableFuture<BlockSelection> readPrefab(@Nonnull Path var0) {
      class="kw">return isBinary(var0)
         ? PrefabBufferUtil.readFromFileAsync(var0).thenApply(PrefabBufferSelectionConverter::toBlockSelection)
         : BsonUtil.readDocument(var0, false).thenApply(SelectionPrefabSerializer::deserialize);
   }

   @Nonnull
   class="kw">private class="kw">static CompletableFuture<Void> writePrefab(@Nonnull Path var0, @Nonnull BlockSelection var1) {
      class="kw">return isBinary(var0)
         ? PrefabBufferUtil.writeToFileAsync(PrefabBufferSelectionConverter.toPrefabBuffer(var0, var1), var0)
         : BsonUtil.writeDocument(var0, SelectionPrefabSerializer.serialize(var1), false);
   }

   class="kw">private class="kw">static boolean isBinary(@Nonnull Path var0) {
      class="kw">return var0.toString().endsWith(".lpf");
   }
}