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");
}
}