159 lines
7.0 KiB
Java
159 lines
7.0 KiB
Java
package com.hypixel.hytale.builtin.blockphysics;
|
|
|
|
import com.hypixel.hytale.common.util.ExceptionUtil;
|
|
import com.hypixel.hytale.component.ComponentType;
|
|
import com.hypixel.hytale.component.Holder;
|
|
import com.hypixel.hytale.component.data.unknown.UnknownComponents;
|
|
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
|
|
import com.hypixel.hytale.server.core.prefab.PrefabStore;
|
|
import com.hypixel.hytale.server.core.prefab.selection.buffer.PrefabBufferUtil;
|
|
import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.IPrefabBuffer;
|
|
import com.hypixel.hytale.server.core.universe.world.ValidationOption;
|
|
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
|
import com.hypixel.hytale.server.core.util.FillerBlockUtil;
|
|
import com.hypixel.hytale.server.core.util.io.FileUtil;
|
|
import com.hypixel.hytale.sneakythrow.SneakyThrow;
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.ArrayList;
|
|
import java.util.EnumSet;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Stream;
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
|
|
public class PrefabBufferValidator {
|
|
private static final FillerBlockUtil.FillerFetcher<IPrefabBuffer, Void> FILLER_FETCHER = new FillerBlockUtil.FillerFetcher<IPrefabBuffer, Void>() {
|
|
public int getBlock(IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) {
|
|
return iPrefabBuffer.getBlockId(x, y, z);
|
|
}
|
|
|
|
public int getFiller(IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) {
|
|
return iPrefabBuffer.getFiller(x, y, z);
|
|
}
|
|
|
|
public int getRotationIndex(IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) {
|
|
return iPrefabBuffer.getRotationIndex(x, y, z);
|
|
}
|
|
};
|
|
|
|
@Nonnull
|
|
public static List<String> validateAllPrefabs(@Nonnull List<ValidationOption> list) {
|
|
Set<ValidationOption> options = !list.isEmpty()
|
|
? EnumSet.copyOf(list)
|
|
: EnumSet.of(ValidationOption.BLOCK_STATES, ValidationOption.ENTITIES, ValidationOption.BLOCKS, ValidationOption.BLOCK_FILLER);
|
|
List<String> out = validatePrefabsInPath(PrefabStore.get().getWorldGenPrefabsPath(), options);
|
|
out.addAll(validatePrefabsInPath(PrefabStore.get().getAssetPrefabsPath(), options));
|
|
out.addAll(validatePrefabsInPath(PrefabStore.get().getServerPrefabsPath(), options));
|
|
return out;
|
|
}
|
|
|
|
@Nonnull
|
|
public static List<String> validatePrefabsInPath(@Nonnull Path dataFolder, @Nonnull Set<ValidationOption> options) {
|
|
if (!Files.exists(dataFolder)) {
|
|
return new ArrayList<>();
|
|
} else {
|
|
try {
|
|
List var3;
|
|
try (Stream<Path> stream = Files.walk(dataFolder, FileUtil.DEFAULT_WALK_TREE_OPTIONS_ARRAY)) {
|
|
var3 = stream.<String>map(path -> {
|
|
if (Files.isRegularFile(path) && path.toString().endsWith(".prefab.json")) {
|
|
try {
|
|
IPrefabBuffer prefab = PrefabBufferUtil.getCached(path);
|
|
|
|
String var4;
|
|
try {
|
|
String results = validate(prefab, options);
|
|
var4 = results != null ? path + "\n" + results : null;
|
|
} finally {
|
|
prefab.release();
|
|
}
|
|
|
|
return var4;
|
|
} catch (Throwable var9) {
|
|
return path + "\n\t" + ExceptionUtil.combineMessages(var9, "\n\t");
|
|
}
|
|
} else {
|
|
return null;
|
|
}
|
|
}).filter(Objects::nonNull).collect(Collectors.toList());
|
|
}
|
|
|
|
return var3;
|
|
} catch (IOException var7) {
|
|
throw SneakyThrow.sneakyThrow(var7);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
public static String validate(@Nonnull IPrefabBuffer prefab, @Nonnull Set<ValidationOption> options) {
|
|
ComponentType<EntityStore, UnknownComponents<EntityStore>> unknownComponentType = EntityStore.REGISTRY.getUnknownComponentType();
|
|
StringBuilder sb = new StringBuilder();
|
|
int offsetX = prefab.getAnchorX();
|
|
int offsetY = prefab.getAnchorY();
|
|
int offsetZ = prefab.getAnchorZ();
|
|
IPrefabBuffer.RawBlockConsumer<Void> legacyValidator = WorldValidationUtil.blockValidator(offsetX, offsetY, offsetZ, sb, options);
|
|
prefab.forEachRaw(
|
|
IPrefabBuffer.iterateAllColumns(),
|
|
(x, y, z, mask, blockId, chance, holder, supportValue, rotation, filler, o) -> {
|
|
legacyValidator.accept(x, y, z, mask, blockId, chance, holder, supportValue, rotation, filler, o);
|
|
if (options.contains(ValidationOption.BLOCK_FILLER)) {
|
|
FillerBlockUtil.ValidationResult fillerResult = FillerBlockUtil.validateBlock(x, y, z, blockId, rotation, filler, prefab, null, FILLER_FETCHER);
|
|
switch (fillerResult) {
|
|
case OK:
|
|
default:
|
|
break;
|
|
case INVALID_BLOCK: {
|
|
BlockType blockType = BlockType.getAssetMap().getAsset(blockId);
|
|
sb.append("\tBlock ")
|
|
.append(blockType != null ? blockType.getId() : "<missing>")
|
|
.append(" at ")
|
|
.append(x)
|
|
.append(", ")
|
|
.append(y)
|
|
.append(", ")
|
|
.append(z)
|
|
.append(" is not valid filler")
|
|
.append('\n');
|
|
break;
|
|
}
|
|
case INVALID_FILLER: {
|
|
BlockType blockType = BlockType.getAssetMap().getAsset(blockId);
|
|
sb.append("\tBlock ")
|
|
.append(blockType != null ? blockType.getId() : "<missing>")
|
|
.append(" at ")
|
|
.append(x)
|
|
.append(", ")
|
|
.append(y)
|
|
.append(", ")
|
|
.append(z)
|
|
.append(" has invalid/missing filler blocks")
|
|
.append('\n');
|
|
}
|
|
}
|
|
}
|
|
},
|
|
(x, y, z, fluidId, level, unused) -> {},
|
|
(x, z, holders, o) -> {
|
|
if (holders != null) {
|
|
if (options.contains(ValidationOption.ENTITIES)) {
|
|
for (Holder<EntityStore> entityHolder : holders) {
|
|
UnknownComponents<EntityStore> unknownComponents = entityHolder.getComponent(unknownComponentType);
|
|
if (unknownComponents != null && !unknownComponents.getUnknownComponents().isEmpty()) {
|
|
sb.append("\tUnknown Entity Components: ").append(unknownComponents.getUnknownComponents()).append("\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
(Void)null
|
|
);
|
|
return !sb.isEmpty() ? sb.toString() : null;
|
|
}
|
|
}
|