Added alternatives (block states) and block entity information to generated Block enum

This commit is contained in:
jglrxavpok 2020-06-21 23:03:40 +02:00
parent fcc0f5e035
commit 62db9d9c26
10 changed files with 213 additions and 86 deletions

@ -1 +1 @@
Subproject commit 28cb60995d153d5c8eb7bb1bb2e0fd645e3202d0
Subproject commit 896bdf77f313205f7c9732055243d9546d869da2

View File

@ -19,13 +19,14 @@ public class BlockContainer implements Comparable<BlockContainer> {
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<BlockState> states) {
public BlockContainer(int ordinal, NamespaceID id, double hardness, double resistance, NamespaceID blockEntity, BlockState defaultState, List<BlockState> 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<BlockContainer> {
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<BlockContainer> {
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<BlockContainer> {
return this;
}
public BlockContainer setAir() {
isAir = true;
return this;
}
@Override
public String toString() {
return "BlockContainer{" +
@ -136,7 +110,7 @@ public class BlockContainer implements Comparable<BlockContainer> {
", isFlower=" + isFlower +
", isFlowerPot=" + isFlowerPot +
", isCoral=" + isCoral +
", hasBlockEntity=" + hasBlockEntity +
", blockEntity=" + blockEntity +
'}';
}

View File

@ -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<BlockAlternative>", "alternatives", "new ArrayList<BlockAlternative>()");
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<BurgerBlock> 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<String, BurgerTileEntity> 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<BurgerBlock> 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);
}

View File

@ -3,6 +3,9 @@ public class BurgerBlock {
String text_id;
double resistance;
// from tileentities
BurgerTileEntity blockEntity;
@Override
public String toString() {
return "BurgerBlock{" +

View File

@ -0,0 +1,7 @@
public class BurgerTileEntity {
String[] blocks;
String name;
int network_id;
}

View File

@ -12,7 +12,11 @@ public class EnumGenerator {
private String[] parameters;
private List<Method> methods = new LinkedList<>();
private List<Instance> instances = new LinkedList<>();
private List<String> imports = new LinkedList<>();
private List<Field> 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;

View File

@ -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) +
'}';
}
}
}

View File

@ -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) +
'}';
}
}

View File

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

View File

@ -8,7 +8,7 @@
<Loggers>
<Root level="trace">
<AppenderRef ref="STDOUT" level="info"/>
<AppenderRef ref="STDOUT" level="debug"/>
</Root>
</Loggers>
</Configuration>