RuntimeParentIndex interface
Пакет: com.hypixel.hytale.builtin.asseteditor
Файл: com/hypixel/hytale/builtin/asseteditor/AssetInheritanceResolver.java
Методы (1)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
abstract |
AssetPath |
resolveAssetPath resolve(@Nonnull String var1) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.asseteditor;
class="kw">import com.hypixel.hytale.assetstore.AssetMap;
class="kw">import com.hypixel.hytale.assetstore.AssetPack;
class="kw">import com.hypixel.hytale.assetstore.AssetStore;
class="kw">import com.hypixel.hytale.builtin.asseteditor.datasource.DataSource;
class="kw">import com.hypixel.hytale.builtin.asseteditor.util.AssetPathUtil;
class="kw">import com.hypixel.hytale.codec.schema.config.ObjectSchema;
class="kw">import com.hypixel.hytale.codec.schema.config.Schema;
class="kw">import com.hypixel.hytale.common.util.PathUtil;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.protocol.packets.asseteditor.AssetInheritanceTreeNode;
class="kw">import com.hypixel.hytale.server.core.util.BsonUtil;
class="kw">import java.nio.charset.StandardCharsets;
class="kw">import java.nio.file.Path;
class="kw">import java.util.HashSet;
class="kw">import java.util.List;
class="kw">import java.util.Set;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.function.Function;
class="kw">import java.util.function.Supplier;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.bson.BsonDocument;
class="kw">import org.bson.BsonValue;
class="kw">final class AssetInheritanceResolver {
class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
class="kw">private class="kw">static class="kw">final int MAX_DEPTH = 64;
@Nonnull
class="kw">private class="kw">final Supplier<List<AssetPack>> assetPacks;
@Nonnull
class="kw">private class="kw">final Function<String, DataSource> dataSourceByPack;
AssetInheritanceResolver(@Nonnull Supplier<List<AssetPack>> var1, @Nonnull Function<String, DataSource> var2) {
this.assetPacks = var1;
this.dataSourceByPack = var2;
}
@Nullable
AssetInheritanceTreeNode[] resolveAncestors(@Nonnull BsonDocument var1, @Nonnull Schema var2, @Nonnull AssetStore var3, @Nonnull AssetPath var4) {
String var5 = findParentPropertyKey(var2);
if (var5 == null) {
class="kw">return null;
}
AssetInheritanceResolver.ResolutionContext var6 = new AssetInheritanceResolver.ResolutionContext(
var5, this.buildRuntimeIndex(var3), AssetPathUtil.PATH_DIR_SERVER.resolve(var3.getPath()), var3.getExtension()
);
class="kw">return this.resolveAncestors(var1, var6, var4);
}
@Nullable
AssetInheritanceTreeNode[] resolveAncestors(@Nonnull BsonDocument var1, @Nonnull AssetInheritanceResolver.ResolutionContext var2, @Nonnull AssetPath var3) {
HashSet var4 = new HashSet<>();
var4.add(var3);
class="kw">return this.buildAncestors(var1, var2, var4, 1);
}
@Nonnull
class="kw">private AssetInheritanceResolver.RuntimeParentIndex buildRuntimeIndex(@Nonnull AssetStore var1) {
class="kw">return var2 -> {
Object var3 = var1.decodeStringKey(var2);
if (var3 == null) {
class="kw">return null;
} else {
AssetMap var4 = var1.getAssetMap();
Path var5 = var4.getPath(var3);
String var6 = var4.getAssetPack(var3);
if (var5 != null && var6 != null) {
DataSource var7 = this.dataSourceByPack.apply(var6);
class="kw">return var7 == null ? null : new AssetPath(var6, PathUtil.relativizePretty(var7.getRootPath(), var5));
} else {
class="kw">return null;
}
}
};
}
@Nullable
class="kw">private class="kw">static String findParentPropertyKey(@Nonnull Schema var0) {
Schema.SchemaTypeField var1 = var0.getHytaleSchemaTypeField();
if (var1 != null && var1.getParentPropertyKey() != null) {
class="kw">return var1.getParentPropertyKey();
}
if (var0 class="kw">instanceof ObjectSchema var2 && var2.getProperties() != null) {
for (Entry var4 : var2.getProperties().entrySet()) {
if (var4.getValue().getHytaleParent() != null) {
class="kw">return var4.getKey();
}
}
}
class="kw">return null;
}
@Nullable
class="kw">private AssetInheritanceTreeNode[] buildAncestors(
@Nonnull BsonDocument var1, @Nonnull AssetInheritanceResolver.ResolutionContext var2, @Nonnull Set<AssetPath> var3, int var4
) class="kw">throws AssetInheritanceResolver.InheritanceResolutionException {
BsonValue var5 = var1.get(var2.parentPropertyKey());
if (var5 == null || !var5.isString()) {
class="kw">return null;
}
if (var4 >= 64) {
throw new AssetInheritanceResolver.InheritanceResolutionException("Inheritance chain exceeds maximum depth of 64");
}
String var6 = var5.asString().getValue();
AssetPath var7 = this.locateParent(var2, var6);
if (var7 == null) {
throw new AssetInheritanceResolver.InheritanceResolutionException("Unable to resolve parent asset id '" + var6 + "'");
}
if (!var3.add(var7)) {
throw new AssetInheritanceResolver.InheritanceResolutionException("Cyclic inheritance detected at '" + var7 + "'");
}
DataSource var8 = this.dataSourceByPack.apply(var7.packId());
if (var8 == null) {
throw new AssetInheritanceResolver.InheritanceResolutionException("No data source for pack '" + var7.packId() + "'");
}
byte[] var9 = var8.getAssetBytes(var7.path());
if (var9 == null) {
throw new AssetInheritanceResolver.InheritanceResolutionException("Failed to read parent asset '" + var7 + "'");
}
BsonDocument var10;
try {
var10 = BsonDocument.parse(new String(var9, StandardCharsets.UTF_8));
} catch (RuntimeException var12) {
throw new AssetInheritanceResolver.InheritanceResolutionException("Failed to parse parent asset '" + var7 + "'", var12);
}
AssetInheritanceTreeNode[] var11 = this.buildAncestors(var10, var2, var3, var4 + 1);
class="kw">return new AssetInheritanceTreeNode[]{new AssetInheritanceTreeNode(var7.toPacket(), BsonUtil.toJson(var10), var11)};
}
@Nullable
class="kw">private AssetPath locateParent(@Nonnull AssetInheritanceResolver.ResolutionContext var1, @Nonnull String var2) {
AssetPath var3 = var1.runtimeIndex().resolve(var2);
class="kw">return var3 != null ? var3 : this.locateParentByScanning(var1, var2);
}
@Nullable
class="kw">private AssetPath locateParentByScanning(@Nonnull AssetInheritanceResolver.ResolutionContext var1, @Nonnull String var2) {
List var3 = this.assetPacks.get();
for (int var4 = var3.size() - 1; var4 >= 0; var4--) {
AssetPack var5 = var3.get(var4);
DataSource var6 = this.dataSourceByPack.apply(var5.getName());
if (var6 != null) {
List var7 = var6.getAssetTree().findAssetFilesByFilename(var1.storeDirectory(), var2 + var1.extension());
if (!var7.isEmpty()) {
Path var8 = var7.get(var7.size() - 1);
if (var7.size() > 1) {
LOGGER.at(Level.WARNING)
.log("Parent asset id '%s' matches %d files in pack '%s'. Using the last by path sort: '%s'.", var2, var7.size(), var5.getName(), var8);
} else {
LOGGER.at(Level.INFO)
.log("Resolved parent asset id '%s' by file scan to '%s' in pack '%s'. It did not load at runtime.", var2, var8, var5.getName());
}
class="kw">return new AssetPath(var5.getName(), var8);
}
}
}
class="kw">return null;
}
class="kw">static class="kw">final class InheritanceResolutionException class="kw">extends RuntimeException {
InheritanceResolutionException(@Nonnull String var1) {
super(var1);
}
InheritanceResolutionException(@Nonnull String var1, @Nonnull Throwable var2) {
super(var1, var2);
}
}
record ResolutionContext(
@Nonnull String parentPropertyKey,
@Nonnull AssetInheritanceResolver.RuntimeParentIndex runtimeIndex,
@Nonnull Path storeDirectory,
@Nonnull String extension
) {
ResolutionContext {
}
}
@FunctionalInterface
class="kw">interface RuntimeParentIndex {
@Nullable
AssetPath resolve(@Nonnull String var1);
}
}