From 2029ba800d5a00b9e85eefeff1e737f01a55341e Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Fri, 30 Dec 2022 04:00:06 -0800 Subject: [PATCH] Begin parsing block mappings (still much to do!) --- .../mappings/versions/MappingsReader_v1.java | 82 ++++++++++++++++++- .../populator/BlockRegistryPopulator.java | 48 +++++++---- 2 files changed, 111 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index 6f46c7f56..88a31b35b 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -28,11 +28,17 @@ package org.geysermc.geyser.registry.mappings.versions; import com.fasterxml.jackson.databind.JsonNode; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockData; +import org.geysermc.geyser.api.block.custom.CustomBlockPermutation; +import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; import org.geysermc.geyser.api.item.custom.CustomItemData; import org.geysermc.geyser.api.item.custom.CustomItemOptions; import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException; +import org.geysermc.geyser.level.block.GeyserCustomBlockComponents; +import org.geysermc.geyser.level.block.GeyserCustomBlockData; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.function.BiConsumer; public class MappingsReader_v1 extends MappingsReader { @@ -157,6 +163,80 @@ public class MappingsReader_v1 extends MappingsReader { throw new InvalidCustomMappingsFileException("A block entry has no name"); } - return null; + JsonNode stateOverrides = node.get("state_overrides"); + + CustomBlockData customBlockData = new GeyserCustomBlockData.CustomBlockDataBuilder() + .name(name) + .components(createCustomBlockComponents(node)) + // TODO: need to parse state data to find these, e.g. [east=none,north=none,power=1,south=none,west=none] + // TODO: add possible values for all blockstates to mappings generator + // .booleanProperty() + // .intProperty() + // .stringProperty() + .permutations(createCustomBlockPermutations(stateOverrides)) + .build(); + + return customBlockData; } + + private List createCustomBlockPermutations(JsonNode node) { + List permutations = new ArrayList<>(); + + if (node != null && node.isObject()) { + node.fields().forEachRemaining(entry -> { + String key = entry.getKey(); + JsonNode value = entry.getValue(); + if (value.isObject()) { + value.forEach(data -> { + permutations.add(new CustomBlockPermutation(createCustomBlockComponents(data), createCustomBlockPropertyQuery(key))); + }); + } + }); + } + + return permutations; + } + + private CustomBlockComponents createCustomBlockComponents(JsonNode node) { + CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder() + // .selectionBox() + // .collisionBox() + // .displayName() + // .geometry() + // .materialInstance() + // .destroyTime() + // .friction() + // .lightEmission() + // .lightDampening() + // .rotation() + // .placeAir() + .build(); + + JsonNode materialInstances = node.get("material_instances"); + // TODO: loop through material instances and add component for each to components + + return components; + } + + private String createCustomBlockPropertyQuery(String state) { + String list = state.substring(1, state.length() - 1); + String[] conditions = list.split(","); + String[] queries = new String[conditions.length]; + + for (int i = 0; i < conditions.length; i++) { + String[] keyval = conditions[i].split("=", 2); + if (keyval[1].equals("true")) { + queries[i] = String.format("query.block_property('%s') == %b", keyval[0], 1); + } else if (keyval[1].equals("false")) { + queries[i] = String.format("query.block_property('%s') == %b", keyval[0], 0); + } else if (keyval[1].matches("-?\\d+")) { + queries[i] = String.format("query.block_property('%s') == %b", keyval[0], Integer.parseInt(keyval[1])); + } else { + queries[i] = String.format("query.block_property('%s') == '%b'", keyval[0], keyval[1]); + } + } + + return String.join(" && ", queries); + } + } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index f5027d9ca..c007a17e3 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -25,22 +25,21 @@ package org.geysermc.geyser.registry.populator; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.google.common.collect.ImmutableMap; -import com.nukkitx.nbt.*; -import com.nukkitx.protocol.bedrock.data.BlockPropertyData; -import com.nukkitx.protocol.bedrock.v544.Bedrock_v544; -import com.nukkitx.protocol.bedrock.v560.Bedrock_v560; - -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; -import it.unimi.dsi.fastutil.objects.*; +import java.io.DataInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.zip.GZIPInputStream; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.block.custom.CustomBlockData; import org.geysermc.geyser.api.block.custom.CustomBlockState; -import org.geysermc.geyser.api.block.custom.component.BoxComponent; import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.registry.BlockRegistries; @@ -48,12 +47,25 @@ import org.geysermc.geyser.registry.type.BlockMapping; import org.geysermc.geyser.registry.type.BlockMappings; import org.geysermc.geyser.util.BlockUtils; -import java.io.DataInputStream; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.function.BiFunction; -import java.util.zip.GZIPInputStream; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.google.common.collect.ImmutableMap; +import com.nukkitx.nbt.NBTInputStream; +import com.nukkitx.nbt.NbtList; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; +import com.nukkitx.nbt.NbtType; +import com.nukkitx.protocol.bedrock.data.BlockPropertyData; +import com.nukkitx.protocol.bedrock.v544.Bedrock_v544; +import com.nukkitx.protocol.bedrock.v560.Bedrock_v560; + +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntMaps; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectIntPair; /** * Populates the block registries.