diff --git a/prismarine-minecraft-data b/prismarine-minecraft-data index 28cb60995..896bdf77f 160000 --- a/prismarine-minecraft-data +++ b/prismarine-minecraft-data @@ -1 +1 @@ -Subproject commit 28cb60995d153d5c8eb7bb1bb2e0fd645e3202d0 +Subproject commit 896bdf77f313205f7c9732055243d9546d869da2 diff --git a/src/generators/java/BlockContainer.java b/src/generators/java/BlockContainer.java index 476701f4b..7b2212ca7 100644 --- a/src/generators/java/BlockContainer.java +++ b/src/generators/java/BlockContainer.java @@ -19,13 +19,14 @@ public class BlockContainer implements Comparable { private boolean isFlower; private boolean isFlowerPot; private boolean isCoral; - private boolean hasBlockEntity; + private NamespaceID blockEntity; - public BlockContainer(int ordinal, NamespaceID id, double hardness, double resistance, BlockState defaultState, List states) { + public BlockContainer(int ordinal, NamespaceID id, double hardness, double resistance, NamespaceID blockEntity, BlockState defaultState, List states) { this.ordinal = ordinal; this.id = id; this.hardness = hardness; this.resistance = resistance; + this.blockEntity = blockEntity; this.defaultState = defaultState; this.states = states; } @@ -50,18 +51,6 @@ public class BlockContainer implements Comparable { return isAir; } - public boolean isCoral() { - return isCoral; - } - - public boolean isFlowerPot() { - return isFlowerPot; - } - - public boolean isFlower() { - return isFlower; - } - public boolean isLiquid() { return isLiquid; } @@ -82,28 +71,8 @@ public class BlockContainer implements Comparable { return resistance; } - public boolean hasBlockEntity() { - return hasBlockEntity; - } - - public BlockContainer setHasBlockEntity() { - hasBlockEntity = true; - return this; - } - - public BlockContainer setCoral() { - isCoral = true; - return this; - } - - public BlockContainer setFlowerPot() { - isFlowerPot = true; - return this; - } - - public BlockContainer setFlower() { - isFlower = true; - return this; + public NamespaceID getBlockEntityName() { + return blockEntity; } public BlockContainer setLiquid() { @@ -121,6 +90,11 @@ public class BlockContainer implements Comparable { return this; } + public BlockContainer setAir() { + isAir = true; + return this; + } + @Override public String toString() { return "BlockContainer{" + @@ -136,7 +110,7 @@ public class BlockContainer implements Comparable { ", isFlower=" + isFlower + ", isFlowerPot=" + isFlowerPot + ", isCoral=" + isCoral + - ", hasBlockEntity=" + hasBlockEntity + + ", blockEntity=" + blockEntity + '}'; } diff --git a/src/generators/java/BlockEnumGenerator.java b/src/generators/java/BlockEnumGenerator.java index 7f126d575..214d412a6 100644 --- a/src/generators/java/BlockEnumGenerator.java +++ b/src/generators/java/BlockEnumGenerator.java @@ -2,6 +2,7 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import net.minestom.server.instance.block.BlockAlternative; import net.minestom.server.registry.ResourceGatherer; import net.minestom.server.utils.NamespaceID; import org.slf4j.Logger; @@ -75,18 +76,75 @@ public class BlockEnumGenerator { String folder = packageName.replace(".", "/"); String className = "TmpBlock"; EnumGenerator blockGenerator = new EnumGenerator(packageName, className); - blockGenerator.setParams("String namespaceID", "short defaultID", "double hardness", "double resistance", "boolean isAir", "boolean isSolid"); - blockGenerator.addMethod("getId", "short", "return defaultID;"); - blockGenerator.addMethod("isAir", "boolean", "return isAir;"); - blockGenerator.addMethod("isSolid", "boolean", "return isSolid;"); - blockGenerator.addMethod("getHardness", "double", "return hardness;"); - blockGenerator.addMethod("getResistance", "double", "return resistance;"); - blockGenerator.addMethod("breaksInstantaneously", "boolean", "return hardness == 0;"); + blockGenerator.addImport(NamespaceID.class.getCanonicalName()); + blockGenerator.addImport(BlockAlternative.class.getCanonicalName()); + blockGenerator.addImport(List.class.getCanonicalName()); + blockGenerator.addImport(ArrayList.class.getCanonicalName()); + blockGenerator.addImport(Arrays.class.getCanonicalName()); + blockGenerator.addHardcodedField("List", "alternatives", "new ArrayList()"); + blockGenerator.setParams("String namespaceID", "short defaultID", "double hardness", "double resistance", "boolean isAir", "boolean isSolid", "NamespaceID blockEntity"); + blockGenerator.addMethod("getId", "()", "short", "return defaultID;"); + blockGenerator.addMethod("isAir", "()", "boolean", "return isAir;"); + blockGenerator.addMethod("hasBlockEntity", "()", "boolean", "return blockEntity != null;"); + blockGenerator.addMethod("getBlockEntityName", "()", "NamespaceID", "return blockEntity;"); + blockGenerator.addMethod("isSolid", "()", "boolean", "return isSolid;"); + blockGenerator.addMethod("getHardness", "()", "double", "return hardness;"); + blockGenerator.addMethod("getResistance", "()", "double", "return resistance;"); + blockGenerator.addMethod("breaksInstantaneously", "()", "boolean", "return hardness == 0;"); + blockGenerator.addPrivateMethod("addBlockAlternative", "(BlockAlternative alternative)", "void", "alternatives.add(alternative);"); + String[] withPropertiesLines = { + "for (BlockAlternative alt : alternatives) {", + "\tif (Arrays.equals(alt.getProperties(), properties)) {", + "\t\treturn alt.getId();", + "\t}", + "}", + "return defaultID;" + }; + blockGenerator.addPrivateMethod("withProperties", "(String... properties)", "short", withPropertiesLines); + blockGenerator.appendToConstructor("alternatives.add(new BlockAlternative(defaultID));"); LOGGER.debug("Generating enum"); + StringBuilder staticBlock = new StringBuilder(); for (BlockContainer block : blocks) { - blockGenerator.addInstance(block.getId().getPath().toUpperCase(), "\""+block.getId().toString()+"\"", "(short) "+block.getDefaultState().getId(), block.getHardness(), block.getResistance(), block.isAir(), block.isSolid()); + String instanceName = block.getId().getPath().toUpperCase(); + blockGenerator.addInstance(instanceName, + "\""+block.getId().toString()+"\"", + "(short) "+block.getDefaultState().getId(), + block.getHardness(), + block.getResistance(), + block.isAir(), + block.isSolid(), + block.getBlockEntityName() != null ? "NamespaceID.from(\""+block.getBlockEntityName()+"\")" : "null" + ); + + // do not add alternative for default states. This will be added by default inside the constructor + if(block.getStates().size() > 1) { + staticBlock.append("\t"); + staticBlock.append("{ // block alternatives of "+instanceName); + staticBlock.append("\n"); + for(BlockContainer.BlockState state : block.getStates()) { + if(state == block.getDefaultState()) + continue; + // generate BlockAlternative instance that will be used to lookup block alternatives + + staticBlock.append("\t\t"); + staticBlock.append(instanceName).append(".addBlockAlternative("); + staticBlock.append("new BlockAlternative("); + staticBlock.append("(short) ").append(state.getId()); + + if(state.getProperties() != null) { + for(var property : state.getProperties().entrySet()) { + staticBlock.append(", "); + staticBlock.append("\"").append(property.getKey()).append("=").append(property.getValue()).append("\""); + } + } + staticBlock.append(")").append(");\n"); + } + staticBlock.append("\t}\n"); + } } + blockGenerator.setStaticInitBlock(staticBlock.toString()); + File classFolder = new File(targetPart+"/"+folder); if(!classFolder.exists()) { classFolder.mkdirs(); @@ -124,13 +182,16 @@ public class BlockEnumGenerator { BlockContainer.BlockState defaultState = new BlockContainer.BlockState(data.defaultState.id, data.defaultState.properties); - BlockContainer block = new BlockContainer(prismarine.id, data.name, prismarine.hardness, burger.resistance, defaultState, states); + BlockContainer block = new BlockContainer(prismarine.id, data.name, prismarine.hardness, burger.resistance, burger.blockEntity == null ? null : NamespaceID.from(burger.blockEntity.name), defaultState, states); if(!"empty".equals(prismarine.boundingBox)) { block.setSolid(); } if(data.name.equals(NamespaceID.from("minecraft:water")) || data.name.equals(NamespaceID.from("minecraft:lava"))) { block.setLiquid(); } + if(data.name.equals(NamespaceID.from("minecraft:air"))) { + block.setAir(); + } blocks.add(block); } @@ -148,12 +209,26 @@ public class BlockEnumGenerator { private static List parseBlocksFromBurger(Gson gson, String url) throws IOException { try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) { LOGGER.debug("\tConnection established, reading file"); - JsonObject obj = gson.fromJson(bufferedReader, JsonArray.class).get(0).getAsJsonObject().getAsJsonObject("blocks").getAsJsonObject("block"); + JsonObject dictionary = gson.fromJson(bufferedReader, JsonArray.class).get(0).getAsJsonObject(); + JsonObject tileEntityMap = dictionary.getAsJsonObject("tileentity").getAsJsonObject("tileentities"); + + Map block2entityMap = new HashMap<>(); + for(var entry : tileEntityMap.entrySet()) { + BurgerTileEntity te = gson.fromJson(entry.getValue(), BurgerTileEntity.class); + if(te.blocks != null) { + for(String block : te.blocks) { + block2entityMap.put(block, te); + } + } + } + + JsonObject blockMap = dictionary.getAsJsonObject("blocks").getAsJsonObject("block"); LOGGER.debug("\tExtracting blocks"); List blocks = new LinkedList<>(); - for(var entry : obj.entrySet()) { + for(var entry : blockMap.entrySet()) { BurgerBlock block = gson.fromJson(entry.getValue(), BurgerBlock.class); + block.blockEntity = block2entityMap.get(block.text_id); blocks.add(block); } diff --git a/src/generators/java/BurgerBlock.java b/src/generators/java/BurgerBlock.java index b58dd51e4..2985c7441 100644 --- a/src/generators/java/BurgerBlock.java +++ b/src/generators/java/BurgerBlock.java @@ -3,6 +3,9 @@ public class BurgerBlock { String text_id; double resistance; + // from tileentities + BurgerTileEntity blockEntity; + @Override public String toString() { return "BurgerBlock{" + diff --git a/src/generators/java/BurgerTileEntity.java b/src/generators/java/BurgerTileEntity.java new file mode 100644 index 000000000..4b646d751 --- /dev/null +++ b/src/generators/java/BurgerTileEntity.java @@ -0,0 +1,7 @@ +public class BurgerTileEntity { + + String[] blocks; + String name; + int network_id; + +} diff --git a/src/generators/java/EnumGenerator.java b/src/generators/java/EnumGenerator.java index 400bfe95a..7b82bbd2c 100644 --- a/src/generators/java/EnumGenerator.java +++ b/src/generators/java/EnumGenerator.java @@ -12,7 +12,11 @@ public class EnumGenerator { private String[] parameters; private List methods = new LinkedList<>(); private List instances = new LinkedList<>(); + private List imports = new LinkedList<>(); + private List hardcodedFields = new LinkedList<>(); private String enumPackage; + private String staticBlock; + private StringBuilder constructorEnd = new StringBuilder(); public EnumGenerator(String packageName, String enumName) { this.enumPackage = packageName; @@ -24,8 +28,12 @@ public class EnumGenerator { this.parameters = parameters; } - public void addMethod(String name, String returnType, String... lines) { - methods.add(new Method(name, returnType, lines)); + public void addMethod(String name, String signature, String returnType, String... lines) { + methods.add(new Method(true, name, signature, returnType, lines)); + } + + public void addPrivateMethod(String name, String signature, String returnType, String... lines) { + methods.add(new Method(false, name, signature, returnType, lines)); } public void addInstance(String name, Object... parameters) { @@ -36,6 +44,9 @@ public class EnumGenerator { StringBuilder builder = new StringBuilder(); builder.append(COMMENT); builder.append("\npackage ").append(enumPackage).append(";\n"); + for(String imp : imports) { + builder.append("import ").append(imp).append(";\n"); + } builder.append("\npublic enum ").append(enumName).append(" {\n"); // generate instances @@ -54,6 +65,11 @@ public class EnumGenerator { } builder.append(";\n"); + if(staticBlock != null) { + builder.append("\n\tstatic {\n"); + builder.append(staticBlock); + builder.append("\t}\n\n"); + } // generate properties & constructor if(parameters.length != 0) { @@ -64,6 +80,12 @@ public class EnumGenerator { } builder.append("\n"); + // hard coded fields + for(Field hardcoded : hardcodedFields) { + builder.append("\t").append(hardcoded.type).append(" ").append(hardcoded.name).append(" = ").append(hardcoded.value).append(";"); + builder.append("\n"); + } + // constructor builder.append("\t"); builder.append(enumName).append("("); @@ -84,14 +106,21 @@ public class EnumGenerator { builder.append("this.").append(name).append(" = ").append(name).append(";\n"); } + builder.append(constructorEnd); + builder.append("\t}\n"); } // generate methods for(Method m : methods) { builder.append("\n"); - builder.append("\tpublic "); - builder.append(m.returnType).append(" ").append(m.name).append("() {\n"); + builder.append("\t"); + if(m.isPublic) { + builder.append("public "); + } else { + builder.append("private "); + } + builder.append(m.returnType).append(" ").append(m.name).append(m.signature).append(" {\n"); for(String line : m.lines) { builder.append("\t\t").append(line).append("\n"); @@ -108,18 +137,52 @@ public class EnumGenerator { this.enumPackage = enumPackage; } + public void addImport(String canonicalName) { + imports.add(canonicalName); + } + + public void setStaticInitBlock(String staticBlock) { + this.staticBlock = staticBlock; + } + + public void appendToConstructor(String... lines) { + for(String line : lines) { + constructorEnd.append("\t\t").append(line).append("\n"); + } + } + + public void addHardcodedField(String type, String name, String value) { + hardcodedFields.add(new Field(type, name, value)); + } + private class Method { + private final boolean isPublic; private String name; + private String signature; private String returnType; private String[] lines; - private Method(String name, String returnType, String[] lines) { + private Method(boolean isPublic, String name, String signature, String returnType, String[] lines) { + this.isPublic = isPublic; this.name = name; + this.signature = signature; this.returnType = returnType; this.lines = lines; } } + private class Field { + private String type; + private String name; + private String value; + + public Field(String type, String name, String value) { + this.type = type; + this.name = name; + this.value = value; + } + } + private class Instance { private String name; private Object[] parameters; diff --git a/src/main/java/net/minestom/server/instance/block/Block.java b/src/main/java/net/minestom/server/instance/block/Block.java index 84af98819..3dcec355d 100644 --- a/src/main/java/net/minestom/server/instance/block/Block.java +++ b/src/main/java/net/minestom/server/instance/block/Block.java @@ -713,14 +713,14 @@ public enum Block { public void addBlockAlternative(BlockAlternative blockAlternative) { this.blockAlternatives.add(blockAlternative); - blocksMap.put(blockAlternative.id, this); - blocksAlternativesMap.put(blockAlternative.id, blockAlternative); + blocksMap.put(blockAlternative.getId(), this); + blocksAlternativesMap.put(blockAlternative.getId(), blockAlternative); } public short withProperties(String... properties) { for (BlockAlternative blockAlternative : blockAlternatives) { - if (Arrays.equals(blockAlternative.properties, properties)) { - return blockAlternative.id; + if (Arrays.equals(blockAlternative.getProperties(), properties)) { + return blockAlternative.getId(); } } // No id found, return default @@ -1568,30 +1568,4 @@ public enum Block { return Collections.unmodifiableList(blockAlternatives); } - public static class BlockAlternative { - - private short id; - private String[] properties; - - public BlockAlternative(short id, String... properties) { - this.id = id; - this.properties = properties; - } - - public short getId() { - return id; - } - - public String[] getProperties() { - return properties; - } - - @Override - public String toString() { - return "BlockAlternative{" + - "id=" + id + - ", properties=" + Arrays.toString(properties) + - '}'; - } - } } diff --git a/src/main/java/net/minestom/server/instance/block/BlockAlternative.java b/src/main/java/net/minestom/server/instance/block/BlockAlternative.java new file mode 100644 index 000000000..d7606a2b7 --- /dev/null +++ b/src/main/java/net/minestom/server/instance/block/BlockAlternative.java @@ -0,0 +1,30 @@ +package net.minestom.server.instance.block; + +import java.util.Arrays; + +public class BlockAlternative { + + private short id; + private String[] properties; + + public BlockAlternative(short id, String... properties) { + this.id = id; + this.properties = properties; + } + + public short getId() { + return id; + } + + public String[] getProperties() { + return properties; + } + + @Override + public String toString() { + return "BlockAlternative{" + + "id=" + id + + ", properties=" + Arrays.toString(properties) + + '}'; + } +} diff --git a/src/main/java/net/minestom/server/registry/RegistryMain.java b/src/main/java/net/minestom/server/registry/RegistryMain.java index 5075a69fb..93941284b 100644 --- a/src/main/java/net/minestom/server/registry/RegistryMain.java +++ b/src/main/java/net/minestom/server/registry/RegistryMain.java @@ -6,6 +6,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minestom.server.entity.EntityType; import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockAlternative; import net.minestom.server.item.Enchantment; import net.minestom.server.item.Material; import net.minestom.server.particle.Particle; @@ -59,7 +60,7 @@ public class RegistryMain { for (RegistryBlock.BlockState blockState : registryBlock.states) { short id = blockState.id; String[] properties = blockState.propertiesValues.toArray(new String[0]); - Block.BlockAlternative blockAlternative = new Block.BlockAlternative(id, properties); + BlockAlternative blockAlternative = new BlockAlternative(id, properties); block.addBlockAlternative(blockAlternative); } diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index f8c195373..15ff6dede 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file