diff --git a/code-generators/src/main/java/net/minestom/codegen/CodeGenerator.java b/code-generators/src/main/java/net/minestom/codegen/CodeGenerator.java index ce949830b..abbae5bd8 100644 --- a/code-generators/src/main/java/net/minestom/codegen/CodeGenerator.java +++ b/code-generators/src/main/java/net/minestom/codegen/CodeGenerator.java @@ -26,7 +26,7 @@ public class CodeGenerator { this.outputFolder = outputFolder; } - public void generate(InputStream resourceFile, String packageName, String typeName, String loaderName, String generatedName) { + public void generate(InputStream resourceFile, String packageName, String typeName,String loaderName, String generatedName) { if (resourceFile == null) { LOGGER.error("Failed to find resource file for " + typeName); return; @@ -50,7 +50,7 @@ public class CodeGenerator { FieldSpec.builder(typeClass, constantName) .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) .initializer( - // TypeClass.STONE = MaterialLoader.get("minecraft:stone") + // TypeClass.STONE = MaterialLoader.fromNamespaceId("minecraft:stone") "$T.get($S)", loaderClass, namespace @@ -66,7 +66,7 @@ public class CodeGenerator { outputFolder); } - private static void writeFiles(@NotNull List fileList, File outputFolder) { + private void writeFiles(@NotNull List fileList, File outputFolder) { for (JavaFile javaFile : fileList) { try { javaFile.writeTo(outputFolder); diff --git a/code-generators/src/main/java/net/minestom/codegen/Generators.java b/code-generators/src/main/java/net/minestom/codegen/Generators.java index 71a39e18c..dd19040fd 100644 --- a/code-generators/src/main/java/net/minestom/codegen/Generators.java +++ b/code-generators/src/main/java/net/minestom/codegen/Generators.java @@ -1,5 +1,6 @@ package net.minestom.codegen; +import net.minestom.codegen.fluid.FluidGenerator; import net.minestom.codegen.particle.ParticleGenerator; import net.minestom.codegen.potion.PotionEffectGenerator; import net.minestom.codegen.potion.PotionTypeGenerator; @@ -29,6 +30,8 @@ public class Generators { if (true) return; // TODO complete + // Generate fluids + new FluidGenerator(resource("fluids.json"), outputFolder).generate(); // TODO: Generate attributes // new AttributeGenerator( // new File(inputFolder, targetVersion + "_attributes.json"), diff --git a/code-generators/src/main/java/net/minestom/codegen/fluid/FluidGenerator.java b/code-generators/src/main/java/net/minestom/codegen/fluid/FluidGenerator.java new file mode 100644 index 000000000..9321e6b17 --- /dev/null +++ b/code-generators/src/main/java/net/minestom/codegen/fluid/FluidGenerator.java @@ -0,0 +1,144 @@ +package net.minestom.codegen.fluid; + +import com.google.gson.JsonObject; +import com.squareup.javapoet.*; +import net.minestom.codegen.MinestomCodeGenerator; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.lang.model.element.Modifier; +import java.io.File; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Collections; + +public final class FluidGenerator extends MinestomCodeGenerator { + private static final Logger LOGGER = LoggerFactory.getLogger(FluidGenerator.class); + private final InputStream fluidsFile; + private final File outputFolder; + + public FluidGenerator(@Nullable InputStream fluidsFile, @NotNull File outputFolder) { + this.fluidsFile = fluidsFile; + this.outputFolder = outputFolder; + } + + @Override + public void generate() { + if (fluidsFile == null) { + LOGGER.error("Failed to find fluids.json."); + LOGGER.error("Stopped code generation for fluids."); + return; + } + if (!outputFolder.exists() && !outputFolder.mkdirs()) { + LOGGER.error("Output folder for code generation does not exist and could not be created."); + return; + } + // Important classes we use alot + ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID"); + ClassName registriesClassName = ClassName.get("net.minestom.server.registry", "Registries"); + + JsonObject fluids = GSON.fromJson(new InputStreamReader(fluidsFile), JsonObject.class); + ClassName fluidClassName = ClassName.get("net.minestom.server.fluid", "Fluid"); + + // Particle + TypeSpec.Builder fluidClass = TypeSpec.enumBuilder(fluidClassName) + .addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed")) + .addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName()); + + fluidClass.addField( + FieldSpec.builder(namespaceIDClassName, "id") + .addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build() + ); + // static field + fluidClass.addField( + FieldSpec.builder(ArrayTypeName.of(fluidClassName), "VALUES") + .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) + .initializer("values()") + .build() + ); + + fluidClass.addMethod( + MethodSpec.constructorBuilder() + .addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build()) + .addStatement("this.id = id") + .addStatement("$T.fluids.put(id, this)", registriesClassName) + .build() + ); + // Override key method (adventure) + fluidClass.addMethod( + MethodSpec.methodBuilder("key") + .returns(ClassName.get("net.kyori.adventure.key", "Key")) + .addAnnotation(Override.class) + .addAnnotation(NotNull.class) + .addStatement("return this.id") + .addModifiers(Modifier.PUBLIC) + .build() + ); + // getId method + fluidClass.addMethod( + MethodSpec.methodBuilder("getId") + .returns(TypeName.SHORT) + .addStatement("return (short) ordinal()") + .addModifiers(Modifier.PUBLIC) + .build() + ); + // getNamespaceID method + fluidClass.addMethod( + MethodSpec.methodBuilder("getNamespaceID") + .returns(namespaceIDClassName) + .addAnnotation(NotNull.class) + .addStatement("return this.id") + .addModifiers(Modifier.PUBLIC) + .build() + ); + // toString method + fluidClass.addMethod( + MethodSpec.methodBuilder("toString") + .addAnnotation(NotNull.class) + .addAnnotation(Override.class) + .returns(String.class) + // this resolves to [Namespace] + .addStatement("return \"[\" + this.id + \"]\"") + .addModifiers(Modifier.PUBLIC) + .build() + ); + + // fromId Method + fluidClass.addMethod( + MethodSpec.methodBuilder("fromId") + .returns(fluidClassName) + .addAnnotation(Nullable.class) + .addParameter(TypeName.SHORT, "id") + .beginControlFlow("if(id >= 0 && id < VALUES.length)") + .addStatement("return VALUES[id]") + .endControlFlow() + .addStatement("return null") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .build() + ); + + // Use data + fluids.entrySet().forEach(entry -> { + final String fluidName = entry.getKey(); + fluidClass.addEnumConstant(toConstant(fluidName), TypeSpec.anonymousClassBuilder( + "$T.from($S)", + namespaceIDClassName, + fluidName + ).build() + ); + }); + + // Write files to outputFolder + writeFiles( + Collections.singletonList( + JavaFile.builder("net.minestom.server.fluid", fluidClass.build()) + .indent(" ") + .skipJavaLangImports(true) + .build() + ), + outputFolder + ); + } +} diff --git a/code-generators/src/main/java/net/minestom/codegen/util/NameUtil.java b/code-generators/src/main/java/net/minestom/codegen/util/NameUtil.java new file mode 100644 index 000000000..b0fd38471 --- /dev/null +++ b/code-generators/src/main/java/net/minestom/codegen/util/NameUtil.java @@ -0,0 +1,21 @@ +package net.minestom.codegen.util; + +public final class NameUtil { + private NameUtil() { + + } + + public static String convertSnakeCaseToCamelCase(String snakeCase) { + StringBuilder sb = new StringBuilder(snakeCase); + for (int i = 0; i < sb.length(); i++) { + if (sb.charAt(i) == '_') { + sb.deleteCharAt(i); + sb.replace(i, i + 1, String.valueOf(Character.toUpperCase(sb.charAt(i)))); + } + } + + // Capitalize first letter. + sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); + return sb.toString(); + } +} diff --git a/src/autogenerated/java/net/minestom/server/fluid/Fluid.java b/src/autogenerated/java/net/minestom/server/fluid/Fluid.java new file mode 100644 index 000000000..bcbc20191 --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/fluid/Fluid.java @@ -0,0 +1,62 @@ +package net.minestom.server.fluid; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Keyed; +import net.minestom.server.registry.Registries; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * AUTOGENERATED by FluidGenerator + */ +public enum Fluid implements Keyed { + EMPTY(NamespaceID.from("minecraft:empty")), + + FLOWING_WATER(NamespaceID.from("minecraft:flowing_water")), + + WATER(NamespaceID.from("minecraft:water")), + + FLOWING_LAVA(NamespaceID.from("minecraft:flowing_lava")), + + LAVA(NamespaceID.from("minecraft:lava")); + + private static final Fluid[] VALUES = values(); + + @NotNull + private final NamespaceID id; + + Fluid(@NotNull NamespaceID id) { + this.id = id; + Registries.fluids.put(id, this); + } + + @Override + @NotNull + public Key key() { + return this.id; + } + + public short getId() { + return (short) ordinal(); + } + + @NotNull + public NamespaceID getNamespaceID() { + return this.id; + } + + @NotNull + @Override + public String toString() { + return "[" + this.id + "]"; + } + + @Nullable + public static Fluid fromId(short id) { + if(id >= 0 && id < VALUES.length) { + return VALUES[id]; + } + return null; + } +} diff --git a/src/autogenerated/java/net/minestom/server/registry/Registries.java b/src/autogenerated/java/net/minestom/server/registry/Registries.java index a38cb0e62..dd0aef892 100644 --- a/src/autogenerated/java/net/minestom/server/registry/Registries.java +++ b/src/autogenerated/java/net/minestom/server/registry/Registries.java @@ -2,12 +2,14 @@ package net.minestom.server.registry; import net.kyori.adventure.key.Key; +import net.minestom.server.fluid.Fluid; import net.minestom.server.particle.Particle; import net.minestom.server.potion.PotionEffect; import net.minestom.server.potion.PotionType; import net.minestom.server.sound.SoundEvent; import net.minestom.server.statistic.StatisticType; import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -47,6 +49,12 @@ public final class Registries { @Deprecated public static final HashMap statisticTypes = new HashMap<>(); + /** + * Should only be used for internal code, please use the get* methods. + */ + @Deprecated + public static final HashMap fluids = new HashMap<>(); + /** * Returns the corresponding Particle matching the given id. Returns null if none match. */ @@ -166,4 +174,28 @@ public final class Registries { public static StatisticType getStatisticType(Key key) { return getStatisticType(NamespaceID.from(key)); } + + /** + * Returns the corresponding Fluid matching the given id. Returns 'EMPTY' if none match. + */ + @NotNull + public static Fluid getFluid(String id) { + return getFluid(NamespaceID.from(id)); + } + + /** + * Returns the corresponding Fluid matching the given id. Returns 'EMPTY' if none match. + */ + @NotNull + public static Fluid getFluid(NamespaceID id) { + return fluids.getOrDefault(id, Fluid.EMPTY); + } + + /** + * Returns the corresponding Fluid matching the given key. Returns 'EMPTY' if none match. + */ + @NotNull + public static Fluid getFluid(Key key) { + return getFluid(NamespaceID.from(key)); + } }