Merge pull request #309 from Minestom/new-data-preperation-1.17

Use minestom-data to generate our enums.
This commit is contained in:
TheMode 2021-06-06 10:44:59 +02:00 committed by GitHub
commit aee429add3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 7313 additions and 6377 deletions

9
.gitignore vendored
View File

@ -32,7 +32,7 @@ hs_err_pid*
### Gradle template
.gradle
/build/
**/build/
# Ignore Gradle GUI config
gradle-app.setting
@ -45,6 +45,7 @@ gradle-app.setting
# IDEA files
.idea/
**/out/
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
@ -56,5 +57,7 @@ gradle-app.setting
/.mixin.out/
# When compiling we get a docs folder
/docs
.mixin.out/
**/docs
# The data for generation and the resources is included in this folder
src/main/resources/minecraft_data

6
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "prismarine-minecraft-data"]
path = prismarine-minecraft-data
url = https://github.com/PrismarineJS/minecraft-data
[submodule "MinestomDataGenerator"]
path = MinestomDataGenerator
url = https://github.com/Minestom/MinestomDataGenerator

1
MinestomDataGenerator Submodule

@ -0,0 +1 @@
Subproject commit ed814de6d727a6f4fdb16a23e10d53e9fe357f85

View File

@ -72,14 +72,6 @@ sourceSets {
srcDir 'src/autogenerated/java'
}
}
generators {
java {
srcDir 'src/generators/java'
}
compileClasspath += sourceSets.main.runtimeClasspath
runtimeClasspath += sourceSets.main.runtimeClasspath
}
lwjgl {
java {
srcDir 'src/lwjgl/java'
@ -98,12 +90,6 @@ java {
withSourcesJar()
}
registerFeature("generators") {
usingSourceSet(sourceSets.generators)
withJavadocJar()
withSourcesJar()
}
withJavadocJar()
withSourcesJar()
}
@ -207,9 +193,6 @@ dependencies {
lwjglRuntimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
lwjglRuntimeOnly "org.lwjgl:lwjgl-opengles::$lwjglNatives"
lwjglRuntimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
generatorsImplementation("com.squareup:javapoet:1.13.0")
}
configurations.all {
@ -217,10 +200,22 @@ configurations.all {
exclude group: "org.checkerframework", module: "checker-qual"
}
processResources {
dependsOn("copyData")
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
}
// UPDATE: Update the data to the required version
// This task just copies the json data from the submodule to the src/main/resources/minecraft_data folder
// TODO: Make sure to delete old data from previous versions
task copyData(type: Copy) {
from("MinestomDataGenerator/Minestom-Data/$mcVersion/")
into(new File(project.projectDir, "/src/main/resources/minecraft_data/"))
}

View File

@ -0,0 +1,43 @@
plugins {
id 'java'
id 'application'
// Used to download our data
}
group 'net.minestom.server'
version '1.0'
sourceCompatibility = 1.11
application {
mainClass.set("net.minestom.codegen.Generators")
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'org.jetbrains:annotations:20.1.0'
implementation 'com.squareup:javapoet:1.13.0'
// Logging
implementation 'org.apache.logging.log4j:log4j-core:2.14.0'
// SLF4J is the base logger for most libraries, therefore we can hook it into log4j2.
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.14.0'
// Kotlin stuff
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${project.kotlinVersion}"
implementation "org.jetbrains.kotlin:kotlin-reflect:${project.kotlinVersion}"
}
run {
// Update version
setArgs(
[
// Point to gradle.properties "mcVersion"
project.rootProject.properties["mcVersion"],
// Points to src/main/resources/minecraft_data
project.rootProject.projectDir.getPath() + "${File.separatorChar}src${File.separatorChar}main${File.separatorChar}resources${File.separatorChar}minecraft_data",
// Points to src/autogenerated/java
project.rootProject.projectDir.getPath() + "${File.separatorChar}src${File.separatorChar}autogenerated${File.separatorChar}java"
]
)
dependsOn(project.rootProject.tasks.getByName("copyData"))
}

View File

@ -0,0 +1,97 @@
package net.minestom.codegen;
import net.minestom.codegen.blocks.BlockGenerator;
import net.minestom.codegen.entity.EntityTypeGenerator;
import net.minestom.codegen.fluid.FluidGenerator;
import net.minestom.codegen.item.EnchantmentGenerator;
import net.minestom.codegen.item.MaterialGenerator;
import net.minestom.codegen.particle.ParticleGenerator;
import net.minestom.codegen.potion.PotionEffectGenerator;
import net.minestom.codegen.potion.PotionTypeGenerator;
import net.minestom.codegen.sound.SoundEventGenerator;
import net.minestom.codegen.statistics.StatisticGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
public class Generators {
private static final Logger LOGGER = LoggerFactory.getLogger(Generators.class);
public static void main(String[] args) {
if (args.length < 3) {
LOGGER.error("Usage: <MC version> <source folder> <target folder>");
return;
}
String targetVersion = args[0].replace(".", "_");
File inputFolder = new File(args[1]);
File outputFolder = new File(args[2]);
// Generate blocks
new BlockGenerator(
new File(inputFolder, targetVersion + "_blocks.json"),
new File(inputFolder, targetVersion + "_block_properties.json"),
outputFolder
).generate();
// Generate fluids
new FluidGenerator(
new File(inputFolder, targetVersion + "_fluids.json"),
outputFolder
).generate();
// Generate entities
new EntityTypeGenerator(
new File(inputFolder, targetVersion + "_entities.json"),
outputFolder
).generate();
// Generate items
new MaterialGenerator(
new File(inputFolder, targetVersion + "_items.json"),
outputFolder
).generate();
// Generate enchantments
new EnchantmentGenerator(
new File(inputFolder, targetVersion + "_enchantments.json"),
outputFolder
).generate();
// TODO: Generate attributes
// new AttributeGenerator(
// new File(inputFolder, targetVersion + "_attributes.json"),
// outputFolder
// ).generate();
// Generate potion effects
new PotionEffectGenerator(
new File(inputFolder, targetVersion + "_potion_effects.json"),
outputFolder
).generate();
// Generate potions
new PotionTypeGenerator(
new File(inputFolder, targetVersion + "_potions.json"),
outputFolder
).generate();
// Generate particles
new ParticleGenerator(
new File(inputFolder, targetVersion + "_particles.json"),
outputFolder
).generate();
// Generate sounds
new SoundEventGenerator(
new File(inputFolder, targetVersion + "_sounds.json"),
outputFolder
).generate();
// TODO: Generate villager professions
// new VillagerProfessionGenerator(
// new File(inputFolder, targetVersion + "_villager_professions.json"),
// outputFolder
// ).generate();
// TODO: Generate villager types
// new VillagerTypeGenerator(
// new File(inputFolder, targetVersion + "_villager_types.json"),
// outputFolder
// ).generate();
// Generate statistics
new StatisticGenerator(
new File(inputFolder, targetVersion + "_custom_statistics.json"),
outputFolder
).generate();
LOGGER.info("Finished generating code");
}
}

View File

@ -0,0 +1,29 @@
package net.minestom.codegen;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.squareup.javapoet.JavaFile;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.List;
public abstract class MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(MinestomCodeGenerator.class);
protected static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
public abstract void generate();
protected void writeFiles(@NotNull List<JavaFile> fileList, File outputFolder) {
for (JavaFile javaFile : fileList) {
try {
javaFile.writeTo(outputFolder);
} catch (IOException e) {
LOGGER.error("An error occured while writing source code to the file system.", e);
}
}
}
}

View File

@ -0,0 +1,256 @@
package net.minestom.codegen.attribute;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
public final class AttributeGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(AttributeGenerator.class);
private final File attributesFile;
private final File outputFolder;
public AttributeGenerator(@NotNull File attributesFile, @NotNull File outputFolder) {
this.attributesFile = attributesFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!attributesFile.exists()) {
LOGGER.error("Failed to find attributes.json.");
LOGGER.error("Stopped code generation for attributes.");
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 registryClassName = ClassName.get("net.minestom.server.registry", "Registry");
JsonArray attributes;
try {
attributes = GSON.fromJson(new JsonReader(new FileReader(attributesFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find attributes.json.");
LOGGER.error("Stopped code generation for attributes.");
return;
}
List<JavaFile> filesToWrite = new ArrayList<>();
ClassName attributeClassName = ClassName.get("net.minestom.server.attribute", "Attribute");
// Attribute
TypeSpec.Builder attributeClass = TypeSpec.classBuilder(attributeClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
attributeClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
attributeClass.addField(
FieldSpec.builder(TypeName.DOUBLE, "defaultValue")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
attributeClass.addField(
FieldSpec.builder(TypeName.BOOLEAN, "clientSyncable")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
attributeClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addParameter(ParameterSpec.builder(TypeName.BOOLEAN, "clientSyncable").build())
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "defaultValue").build())
.addStatement("this.id = id")
.addStatement("this.clientSyncable = clientSyncable")
.addStatement("this.defaultValue = defaultValue")
.addModifiers(Modifier.PROTECTED)
.build()
);
// Override key method (adventure)
attributeClass.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
attributeClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getDefaultValue
attributeClass.addMethod(
MethodSpec.methodBuilder("getDefaultValue")
.returns(TypeName.DOUBLE)
.addStatement("return this.defaultValue")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isClientSyncable
attributeClass.addMethod(
MethodSpec.methodBuilder("isClientSyncable")
.returns(TypeName.BOOLEAN)
.addStatement("return this.clientSyncable")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isShared
attributeClass.addMethod(
MethodSpec.methodBuilder("isShared")
.addAnnotation(Deprecated.class)
.returns(TypeName.BOOLEAN)
.addStatement("return this.clientSyncable")
.addModifiers(Modifier.PUBLIC)
.build()
);
// values method
attributeClass.addMethod(
MethodSpec.methodBuilder("values")
.addAnnotation(NotNull.class)
.returns(ParameterizedTypeName.get(ClassName.get(List.class), attributeClassName))
.addStatement("return $T.ATTRIBUTE_REGISTRY.values()", registryClassName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
// toString method
attributeClass.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()
);
// Creating ClampedAttribute
ClassName clampedAttributeClassName = ClassName.get("net.minestom.server.attribute", "ClampedAttribute");
TypeSpec.Builder clampedAttributeClass = TypeSpec.classBuilder(clampedAttributeClassName)
.superclass(attributeClassName)
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
clampedAttributeClass.addField(
FieldSpec.builder(TypeName.DOUBLE, "minValue")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
clampedAttributeClass.addField(
FieldSpec.builder(TypeName.DOUBLE, "maxValue")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
clampedAttributeClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addParameter(ParameterSpec.builder(TypeName.BOOLEAN, "clientSyncable").build())
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "defaultValue").build())
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "minValue").build())
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "maxValue").build())
.addStatement("super(id, clientSyncable, defaultValue)")
.addStatement("this.minValue = minValue")
.addStatement("this.maxValue = maxValue")
.addModifiers(Modifier.PROTECTED)
.build()
);
// getMinValue
clampedAttributeClass.addMethod(
MethodSpec.methodBuilder("getMinValue")
.returns(TypeName.DOUBLE)
.addStatement("return this.minValue")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getMaxValue
clampedAttributeClass.addMethod(
MethodSpec.methodBuilder("getMaxValue")
.returns(TypeName.DOUBLE)
.addStatement("return this.maxValue")
.addModifiers(Modifier.PUBLIC)
.build()
);
CodeBlock.Builder staticBlock = CodeBlock.builder();
// Use data
for (JsonElement a : attributes) {
JsonObject attribute = a.getAsJsonObject();
String attributeName = attribute.get("name").getAsString();
JsonObject range = attribute.getAsJsonObject("range");
if (range == null) {
// Normal attribute
attributeClass.addField(
FieldSpec.builder(
attributeClassName,
attributeName
).initializer(
"new $T($T.from($S), $L, $L)",
attributeClassName,
namespaceIDClassName,
attribute.get("id").getAsString(),
attribute.get("clientSync").getAsBoolean(),
attribute.get("defaultValue").getAsDouble()
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
);
} else {
// ClampedAttribute
attributeClass.addField(
FieldSpec.builder(
attributeClassName,
attributeName
).initializer(
"new $T($T.from($S), $L, $L, $L, $L)",
clampedAttributeClassName,
namespaceIDClassName,
attribute.get("id").getAsString(),
attribute.get("clientSync").getAsBoolean(),
attribute.get("defaultValue").getAsDouble(),
range.get("minValue").getAsDouble(),
range.get("maxValue").getAsDouble()
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
);
}
// Add to static init.
staticBlock.addStatement("$T.ATTRIBUTE_REGISTRY.register($N)", registryClassName, attributeName);
}
attributeClass.addStaticBlock(staticBlock.build());
filesToWrite.add(
JavaFile.builder("net.minestom.server.attribute", attributeClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
);
filesToWrite.add(
JavaFile.builder("net.minestom.server.attribute", clampedAttributeClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
);
// Write files to outputFolder
writeFiles(
filesToWrite,
outputFolder
);
}
}

View File

@ -0,0 +1,415 @@
package net.minestom.codegen.blocks;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import net.minestom.codegen.util.NameUtil;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public final class BlockGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(BlockGenerator.class);
private final File blocksFile;
private final File blockPropertyFile;
private final File outputFolder;
public BlockGenerator(@NotNull File blocksFile, @NotNull File blockPropertyFile, @NotNull File outputFolder) {
this.blocksFile = blocksFile;
this.blockPropertyFile = blockPropertyFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!blocksFile.exists()) {
LOGGER.error("Failed to find blocks.json.");
LOGGER.error("Stopped code generation for blocks.");
return;
}
if (!blockPropertyFile.exists()) {
LOGGER.error("Failed to find block_properties.json.");
LOGGER.error("Stopped code generation for block properties.");
return;
}
if (!outputFolder.exists() && !outputFolder.mkdirs()) {
LOGGER.error("Output folder for code generation does not exist and could not be created.");
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");
JsonArray blocks;
try {
blocks = GSON.fromJson(new JsonReader(new FileReader(blocksFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find blocks.json.");
LOGGER.error("Stopped code generation for blocks.");
return;
}
ClassName blockClassName = ClassName.get("net.minestom.server.instance.block", "Block");
ClassName blockAltClassName = ClassName.get("net.minestom.server.instance.block", "BlockAlternative");
List<JavaFile> filesToWrite = new ArrayList<>();
// Block
TypeSpec.Builder blockClass = TypeSpec.enumBuilder(blockClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
blockClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
blockClass.addField(
FieldSpec.builder(TypeName.SHORT, "defaultID")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
blockClass.addField(
FieldSpec.builder(TypeName.DOUBLE, "hardness")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
blockClass.addField(
FieldSpec.builder(TypeName.DOUBLE, "resistance")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
blockClass.addField(
FieldSpec.builder(TypeName.BOOLEAN, "isAir")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
blockClass.addField(
FieldSpec.builder(TypeName.BOOLEAN, "isSolid")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
blockClass.addField(
FieldSpec.builder(TypeName.BOOLEAN, "blockEntity")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
blockClass.addField(
FieldSpec.builder(TypeName.BOOLEAN, "singleState")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
blockClass.addField(
FieldSpec.builder(ParameterizedTypeName.get(ClassName.get("java.util", "List"), blockAltClassName), "alternatives")
.initializer("new $T<>()", ClassName.get("java.util", "ArrayList"))
.addModifiers(Modifier.PRIVATE, Modifier.FINAL)
.addAnnotation(NotNull.class)
.build()
);
// Block constructor
blockClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addParameter(TypeName.SHORT, "defaultID")
.addParameter(TypeName.DOUBLE, "hardness")
.addParameter(TypeName.DOUBLE, "resistance")
.addParameter(TypeName.BOOLEAN, "isAir")
.addParameter(TypeName.BOOLEAN, "isSolid")
.addParameter(TypeName.BOOLEAN, "blockEntity")
.addParameter(TypeName.BOOLEAN, "singleState")
.addStatement("this.id = id")
.addStatement("this.defaultID = defaultID")
.addStatement("this.hardness = hardness")
.addStatement("this.resistance = resistance")
.addStatement("this.isAir = isAir")
.addStatement("this.isSolid = isSolid")
.addStatement("this.blockEntity = blockEntity")
.addStatement("this.singleState = singleState")
.beginControlFlow("if (singleState)")
.addStatement("addBlockAlternative(new $T(defaultID))", blockAltClassName)
.endControlFlow()
.addStatement("$T.blocks.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
blockClass.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()
);
// addBlockState method
blockClass.addMethod(
MethodSpec.methodBuilder("addBlockAlternative")
.addParameter(ParameterSpec.builder(blockAltClassName, "alternative").addAnnotation(NotNull.class).build())
.addStatement("this.alternatives.add(alternative)")
.addStatement("BlockArray.blocks[alternative.getId()] = this")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.build()
);
// getId method
blockClass.addMethod(
MethodSpec.methodBuilder("getBlockId")
.returns(TypeName.SHORT)
.addStatement("return defaultID")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getName method
blockClass.addMethod(
MethodSpec.methodBuilder("getName")
.addAnnotation(NotNull.class)
.returns(ClassName.get(String.class))
.addStatement("return this.id.asString()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getHardness method
blockClass.addMethod(
MethodSpec.methodBuilder("getHardness")
.returns(TypeName.DOUBLE)
.addStatement("return this.hardness")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getResistance method
blockClass.addMethod(
MethodSpec.methodBuilder("getResistance")
.returns(TypeName.DOUBLE)
.addStatement("return this.resistance")
.addModifiers(Modifier.PUBLIC)
.build()
);
// breakInstantaneously method
blockClass.addMethod(
MethodSpec.methodBuilder("breaksInstantaneously")
.returns(TypeName.BOOLEAN)
.addStatement("return this.hardness == 0")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getBlockStates method
blockClass.addMethod(
MethodSpec.methodBuilder("getAlternatives")
.returns(ParameterizedTypeName.get(ClassName.get(List.class), blockAltClassName))
.addAnnotation(NotNull.class)
.addStatement("return this.alternatives")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL) // Should this be final, for now I guess so.
.build()
);
// isAir method
blockClass.addMethod(
MethodSpec.methodBuilder("isAir")
.returns(TypeName.BOOLEAN)
// UPDATE: Make sure they didn't add new AIR types.
.addStatement("return isAir")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isLiquid method
blockClass.addMethod(
MethodSpec.methodBuilder("isLiquid")
.returns(TypeName.BOOLEAN)
// UPDATE: Make sure they didn't add new liquids.
.addStatement("return this == WATER || this == LAVA")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isSolid method
blockClass.addMethod(
MethodSpec.methodBuilder("isSolid")
.returns(TypeName.BOOLEAN)
// UPDATE: Make sure they didn't add new liquids.
.addStatement("return isSolid")
.addModifiers(Modifier.PUBLIC)
.build()
);
// hasBlockEntity method
blockClass.addMethod(
MethodSpec.methodBuilder("hasBlockEntity")
.returns(TypeName.BOOLEAN)
.addStatement("return blockEntity")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getAlternative method
blockClass.addMethod(
MethodSpec.methodBuilder("getAlternative")
.returns(blockAltClassName)
.addParameter(TypeName.SHORT, "blockId")
.addAnnotation(Nullable.class)
.beginControlFlow("for ($T alt : alternatives) ", blockAltClassName)
.beginControlFlow("if (alt.getId() == blockId)")
.addStatement("return alt")
.endControlFlow()
.endControlFlow()
.addStatement("return null")
.addModifiers(Modifier.PUBLIC)
.build()
);
// withProperties method
blockClass.addMethod(
MethodSpec.methodBuilder("withProperties")
.returns(TypeName.SHORT)
.addParameter(
ParameterSpec.builder(ArrayTypeName.of(String.class), "properties").addAnnotation(NotNull.class).build()
).varargs()
.beginControlFlow("for ($T alt : alternatives)", blockAltClassName)
.beginControlFlow("if ($T.equals(alt.getProperties(), properties))", Arrays.class)
.addStatement("return alt.getId()")
.endControlFlow()
.endControlFlow()
.addStatement("return this.defaultID")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromStateId method
blockClass.addMethod(
MethodSpec.methodBuilder("fromStateId")
.returns(blockClassName)
.addParameter(TypeName.SHORT, "blockStateId")
.addStatement("return BlockArray.blocks[blockStateId]")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
// toString method
blockClass.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()
);
// Staticblock in Block enum
CodeBlock.Builder staticBlock = CodeBlock.builder();
// Use data
for (JsonElement b : blocks) {
JsonObject block = b.getAsJsonObject();
String blockName = block.get("name").getAsString();
JsonArray states = block.get("states").getAsJsonArray();
// Enum constant in Block
blockClass.addEnumConstant(blockName, TypeSpec.anonymousClassBuilder(
"$T.from($S), (short) $L, $L, $L, $L, $L, $L, $L",
namespaceIDClassName,
block.get("id").getAsString(),
block.get("defaultBlockState").getAsShort(),
states.get(0).getAsJsonObject().get("destroySpeed").getAsDouble(),
block.get("explosionResistance").getAsDouble(),
states.get(0).getAsJsonObject().get("isAir").getAsBoolean(),
states.get(0).getAsJsonObject().get("isSolid").getAsBoolean(),
block.get("blockEntity").getAsBoolean(),
states.size() == 1
).build()
);
if (states.size() > 1) {
ClassName blockStateSpecificClassName = ClassName.get(
"net.minestom.server.instance.block.states",
NameUtil.convertSnakeCaseToCamelCase(blockName.toLowerCase())
);
// Common blockStateSpecificClass structure
TypeSpec.Builder blockStateSpecificClass = TypeSpec.classBuilder(blockStateSpecificClassName)
.addAnnotation(
AnnotationSpec.builder(Deprecated.class)
.addMember("since", "$S", "forever")
.addMember("forRemoval", "$L", false).build()
)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL).addJavadoc("Completely internal. DO NOT USE. IF YOU ARE A USER AND FACE A PROBLEM WHILE USING THIS CODE, THAT'S ON YOU.");
// initStates method
MethodSpec.Builder initStatesMethod = MethodSpec.methodBuilder("initStates")
.addJavadoc("Completely internal. DO NOT USE. IF YOU ARE A USER AND FACE A PROBLEM WHILE USING THIS CODE, THAT'S ON YOU.")
.addAnnotation(
AnnotationSpec.builder(Deprecated.class)
.addMember("since", "$S", "forever")
.addMember("forRemoval", "$L", false).build()
)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
// init States methods in block specific classes
for (JsonElement s : states) {
JsonObject state = s.getAsJsonObject();
// block state properties
JsonObject properties = state.get("properties").getAsJsonObject();
if (properties.size() != 0) {
StringBuilder propertiesStr = new StringBuilder();
// has properties
for (Map.Entry<String, JsonElement> entry : properties.entrySet()) {
String key = entry.getKey();
String value = entry.getValue().getAsString().toLowerCase();
propertiesStr.append('"').append(key).append('=').append(value).append("\", ");
}
// Delete last comma and space
propertiesStr.deleteCharAt(propertiesStr.length() - 1);
propertiesStr.deleteCharAt(propertiesStr.length() - 1);
initStatesMethod.addStatement(
"$T.$N.addBlockAlternative(new $T((short) $L, **REPLACE**))".replace("**REPLACE**", propertiesStr.toString()),
blockClassName,
blockName,
blockAltClassName,
state.get("id").getAsShort()
);
} else {
// has no properties
initStatesMethod.addStatement(
"$T.$N.addBlockAlternative(new $T((short) $L))",
blockClassName,
blockName,
blockAltClassName,
state.get("id").getAsShort()
);
}
}
// Add initStates method
blockStateSpecificClass.addMethod(initStatesMethod.build());
// Add initStates method refence to static block
staticBlock.addStatement("$T.initStates()", blockStateSpecificClassName);
// Add BlockStates to list of files we need to write:
filesToWrite.add(
JavaFile.builder("net.minestom.server.instance.block.states", blockStateSpecificClass.build()
)
.indent(" ")
.skipJavaLangImports(true)
.build());
}
}
blockClass.addStaticBlock(staticBlock.build());
// Add ignore deprecations annotation
blockClass.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "$S", "deprecation").build());
// Add Block & BlockState to list of files we need to write:
filesToWrite.add(
JavaFile.builder("net.minestom.server.instance.block", blockClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
);
// Write files to outputFolder
writeFiles(filesToWrite, outputFolder);
}
}

View File

@ -0,0 +1,445 @@
package net.minestom.codegen.entity;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import net.minestom.codegen.util.NameUtil;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
public final class EntityTypeGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(EntityTypeGenerator.class);
private static final Map<String, String> metadata = new HashMap<>() {{
// Class's name (without the Meta suffix) <--> Package
// UPDATE: Handle new entity metadata
// Ambient
// put("AmbientCreature", "net.minestom.server.entity.metadata.ambient");
put("Bat", "net.minestom.server.entity.metadata.ambient");
// Animal
// put("Animal", "net.minestom.server.entity.metadata.animal");
put("AbstractHorse", "net.minestom.server.entity.metadata.animal");
put("Bee", "net.minestom.server.entity.metadata.animal");
put("ChestedHorse", "net.minestom.server.entity.metadata.animal");
put("Chicken", "net.minestom.server.entity.metadata.animal");
put("Cow", "net.minestom.server.entity.metadata.animal");
put("Donkey", "net.minestom.server.entity.metadata.animal");
put("Fox", "net.minestom.server.entity.metadata.animal");
put("Hoglin", "net.minestom.server.entity.metadata.animal");
put("Horse", "net.minestom.server.entity.metadata.animal");
put("Llama", "net.minestom.server.entity.metadata.animal");
put("Mooshroom", "net.minestom.server.entity.metadata.animal");
put("Mule", "net.minestom.server.entity.metadata.animal");
put("Ocelot", "net.minestom.server.entity.metadata.animal");
put("Panda", "net.minestom.server.entity.metadata.animal");
put("Pig", "net.minestom.server.entity.metadata.animal");
put("PolarBear", "net.minestom.server.entity.metadata.animal");
put("Rabbit", "net.minestom.server.entity.metadata.animal");
put("Sheep", "net.minestom.server.entity.metadata.animal");
put("SkeletonHorse", "net.minestom.server.entity.metadata.animal");
put("Strider", "net.minestom.server.entity.metadata.animal");
put("Turtle", "net.minestom.server.entity.metadata.animal");
put("ZombieHorse", "net.minestom.server.entity.metadata.animal");
// Animal - Tameable
// put("TameableAnimal", "net.minestom.server.entity.metadata.animal.tameable");
put("Cat", "net.minestom.server.entity.metadata.animal.tameable");
put("Parrot", "net.minestom.server.entity.metadata.animal.tameable");
put("Wolf", "net.minestom.server.entity.metadata.animal.tameable");
// Arrow
// put("AbstractArrow", "net.minestom.server.entity.metadata.arrow");
put("Arrow", "net.minestom.server.entity.metadata.arrow");
put("SpectralArrow", "net.minestom.server.entity.metadata.arrow");
put("ThrownTrident", "net.minestom.server.entity.metadata.arrow");
// Flying
// put("Flying", "net.minestom.server.entity.metadata.flying");
put("Ghast", "net.minestom.server.entity.metadata.flying");
put("Phantom", "net.minestom.server.entity.metadata.flying");
// Golem
// put("AbstractGolem", "net.minestom.server.entity.metadata.golem");
put("IronGolem", "net.minestom.server.entity.metadata.golem");
put("Shulker", "net.minestom.server.entity.metadata.golem");
put("SnowGolem", "net.minestom.server.entity.metadata.golem");
// Item
put("EyeOfEnder", "net.minestom.server.entity.metadata.item");
put("Fireball", "net.minestom.server.entity.metadata.item");
put("ItemContaining", "net.minestom.server.entity.metadata.item");
put("ItemEntity", "net.minestom.server.entity.metadata.item");
put("SmallFireball", "net.minestom.server.entity.metadata.item");
put("Snowball", "net.minestom.server.entity.metadata.item");
put("ThrownEgg", "net.minestom.server.entity.metadata.item");
put("ThrownEnderPearl", "net.minestom.server.entity.metadata.item");
put("ThrownExperienceBottle", "net.minestom.server.entity.metadata.item");
put("ThrownPotion", "net.minestom.server.entity.metadata.item");
// Minecart
// put("AbstractMinecart", "net.minestom.server.entity.metadata.minecart");
// put("AbstractMinecartContainer", "net.minestom.server.entity.metadata.minecart");
put("ChestMinecart", "net.minestom.server.entity.metadata.minecart");
put("CommandBlockMinecart", "net.minestom.server.entity.metadata.minecart");
put("FurnaceMinecart", "net.minestom.server.entity.metadata.minecart");
put("HopperMinecart", "net.minestom.server.entity.metadata.minecart");
put("Minecart", "net.minestom.server.entity.metadata.minecart");
put("SpawnerMinecart", "net.minestom.server.entity.metadata.minecart");
put("TntMinecart", "net.minestom.server.entity.metadata.minecart");
// Monster
// put("Monster", "net.minestom.server.entity.metadata.monster");
// put("BasePiglin", "net.minestom.server.entity.metadata.monster");
put("Blaze", "net.minestom.server.entity.metadata.monster");
put("CaveSpider", "net.minestom.server.entity.metadata.monster");
put("Creeper", "net.minestom.server.entity.metadata.monster");
put("ElderGuardian", "net.minestom.server.entity.metadata.monster");
put("Enderman", "net.minestom.server.entity.metadata.monster");
put("Endermite", "net.minestom.server.entity.metadata.monster");
put("Giant", "net.minestom.server.entity.metadata.monster");
put("Guardian", "net.minestom.server.entity.metadata.monster");
put("PiglinBrute", "net.minestom.server.entity.metadata.monster");
put("Piglin", "net.minestom.server.entity.metadata.monster");
put("Silverfish", "net.minestom.server.entity.metadata.monster");
put("Spider", "net.minestom.server.entity.metadata.monster");
put("Vex", "net.minestom.server.entity.metadata.monster");
put("Wither", "net.minestom.server.entity.metadata.monster");
put("Zoglin", "net.minestom.server.entity.metadata.monster");
// Monster - Raider
// put("AbstractIllager", "net.minestom.server.entity.metadata.monster.raider")
put("Evoker", "net.minestom.server.entity.metadata.monster.raider");
put("Illusioner", "net.minestom.server.entity.metadata.monster.raider");
put("Pillager", "net.minestom.server.entity.metadata.monster.raider");
put("Raider", "net.minestom.server.entity.metadata.monster.raider");
put("Ravager", "net.minestom.server.entity.metadata.monster.raider");
put("SpellcasterIllager", "net.minestom.server.entity.metadata.monster.raider");
put("Vindicator", "net.minestom.server.entity.metadata.monster.raider");
put("Witch", "net.minestom.server.entity.metadata.monster.raider");
// Monster - Skeleton
// put("AbstractSkeleton", "net.minestom.server.entity.metadata.monster.skeleton");
put("Skeleton", "net.minestom.server.entity.metadata.monster.skeleton");
put("Stray", "net.minestom.server.entity.metadata.monster.skeleton");
put("WitherSkeleton", "net.minestom.server.entity.metadata.monster.skeleton");
// Monster - Zombie
put("Drowned", "net.minestom.server.entity.metadata.monster.zombie");
put("Husk", "net.minestom.server.entity.metadata.monster.zombie");
put("Zombie", "net.minestom.server.entity.metadata.monster.zombie");
put("ZombieVillager", "net.minestom.server.entity.metadata.monster.zombie");
put("ZombifiedPiglin", "net.minestom.server.entity.metadata.monster.zombie");
// Other
put("AreaEffectCloud", "net.minestom.server.entity.metadata.other");
put("ArmorStand", "net.minestom.server.entity.metadata.other");
put("Boat", "net.minestom.server.entity.metadata.other");
put("DragonFireball", "net.minestom.server.entity.metadata.other");
put("EndCrystal", "net.minestom.server.entity.metadata.other");
put("EnderDragon", "net.minestom.server.entity.metadata.other");
put("EvokerFangs", "net.minestom.server.entity.metadata.other");
put("ExperienceOrb", "net.minestom.server.entity.metadata.other");
put("FallingBlock", "net.minestom.server.entity.metadata.other");
put("FireworkRocket", "net.minestom.server.entity.metadata.other");
put("FishingHook", "net.minestom.server.entity.metadata.other");
put("ItemFrame", "net.minestom.server.entity.metadata.other");
put("LeashKnot", "net.minestom.server.entity.metadata.other");
put("LightningBolt", "net.minestom.server.entity.metadata.other");
put("LlamaSpit", "net.minestom.server.entity.metadata.other");
put("MagmaCube", "net.minestom.server.entity.metadata.other");
put("Painting", "net.minestom.server.entity.metadata.other");
put("PrimedTnt", "net.minestom.server.entity.metadata.other");
put("ShulkerBullet", "net.minestom.server.entity.metadata.other");
put("Slime", "net.minestom.server.entity.metadata.other");
put("TraderLlama", "net.minestom.server.entity.metadata.other");
put("WitherSkull", "net.minestom.server.entity.metadata.other");
// Villager
// put("AbstractVillager", "net.minestom.server.entity.metadata.villager");
put("Villager", "net.minestom.server.entity.metadata.villager");
put("WanderingTrader", "net.minestom.server.entity.metadata.villager");
// Water
// put("WaterAnimalMeta", "net.minestom.server.entity.metadata.water")
put("Squid", "net.minestom.server.entity.metadata.water");
put("Dolphin", "net.minestom.server.entity.metadata.water");
// Water - Fish
// put("AbstractFish", "net.minestom.server.entity.metadata.water.fish");
put("Cod", "net.minestom.server.entity.metadata.water.fish");
put("Pufferfish", "net.minestom.server.entity.metadata.water.fish");
put("Salmon", "net.minestom.server.entity.metadata.water.fish");
put("TropicalFish", "net.minestom.server.entity.metadata.water.fish");
// Player
put("Player", "net.minestom.server.entity.metadata");
}};
private final File entitiesFile;
private final File outputFolder;
public EntityTypeGenerator(@NotNull File entitiesFile, @NotNull File outputFolder) {
this.entitiesFile = entitiesFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!entitiesFile.exists()) {
LOGGER.error("Failed to find entities.json.");
LOGGER.error("Stopped code generation for entities.");
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");
JsonArray entities;
try {
entities = GSON.fromJson(new JsonReader(new FileReader(entitiesFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find entities.json.");
LOGGER.error("Stopped code generation for entities.");
return;
}
ClassName entityClassName = ClassName.get("net.minestom.server.entity", "EntityType");
// Particle
TypeSpec.Builder entityClass = TypeSpec.enumBuilder(entityClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
entityClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
entityClass.addField(
FieldSpec.builder(TypeName.DOUBLE, "width")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
entityClass.addField(
FieldSpec.builder(TypeName.DOUBLE, "height")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
entityClass.addField(
FieldSpec.builder(
ParameterizedTypeName.get(
ClassName.get(BiFunction.class),
ClassName.get("net.minestom.server.entity", "Entity"),
ClassName.get("net.minestom.server.entity", "Metadata"),
ClassName.get("net.minestom.server.entity.metadata", "EntityMeta")
),
"metaConstructor"
)
.addModifiers(Modifier.PRIVATE, Modifier.FINAL)
.addAnnotation(NotNull.class)
.build()
);
entityClass.addField(
FieldSpec.builder(
ClassName.get("net.minestom.server.entity", "EntitySpawnType"),
"spawnType"
)
.addModifiers(Modifier.PRIVATE, Modifier.FINAL)
.addAnnotation(NotNull.class)
.build()
);
// static field
entityClass.addField(
FieldSpec.builder(ArrayTypeName.of(entityClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
entityClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "width").build())
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "height").build())
.addParameter(
ParameterSpec.builder(
ParameterizedTypeName.get(
ClassName.get(BiFunction.class),
ClassName.get("net.minestom.server.entity", "Entity"),
ClassName.get("net.minestom.server.entity", "Metadata"),
ClassName.get("net.minestom.server.entity.metadata", "EntityMeta")
),
"metaConstructor"
)
.addAnnotation(NotNull.class)
.build()
)
.addParameter(
ParameterSpec.builder(
ClassName.get("net.minestom.server.entity", "EntitySpawnType"),
"spawnType"
)
.addAnnotation(NotNull.class)
.build()
)
.addStatement("this.id = id")
.addStatement("this.width = width")
.addStatement("this.height = height")
.addStatement("this.metaConstructor = metaConstructor")
.addStatement("this.spawnType = spawnType")
.addStatement("$T.entityTypes.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
entityClass.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
entityClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
entityClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getWidth method
entityClass.addMethod(
MethodSpec.methodBuilder("getWidth")
.returns(TypeName.DOUBLE)
.addStatement("return this.width")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getHeight method
entityClass.addMethod(
MethodSpec.methodBuilder("getHeight")
.returns(TypeName.DOUBLE)
.addStatement("return this.height")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getMetaConstructor method
entityClass.addMethod(
MethodSpec.methodBuilder("getMetaConstructor")
.returns(
ParameterizedTypeName.get(
ClassName.get(BiFunction.class),
ClassName.get("net.minestom.server.entity", "Entity"),
ClassName.get("net.minestom.server.entity", "Metadata"),
ClassName.get("net.minestom.server.entity.metadata", "EntityMeta")
)
)
.addStatement("return this.metaConstructor")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getSpawnType method
entityClass.addMethod(
MethodSpec.methodBuilder("getSpawnType")
.returns(ClassName.get("net.minestom.server.entity", "EntitySpawnType"))
.addStatement("return this.spawnType")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
entityClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(entityClassName)
.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()
);
// toString method
entityClass.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()
);
// Use data
for (JsonElement e : entities) {
JsonObject entity = e.getAsJsonObject();
String entityName = entity.get("name").getAsString();
// Get metaClass (this is a little complicated)
String metaClassName = NameUtil.convertSnakeCaseToCamelCase(entityName.toLowerCase());
switch (metaClassName) {
// These are cases where the entity name doesn't fully match up to the meta name.
// UPDATE: Handle new entity names that don't match up to their meta name.
case "Item":
metaClassName = "ItemEntity";
break;
case "Tnt":
metaClassName = "PrimedTnt";
break;
case "FishingBobber":
metaClassName = "FishingHook";
break;
case "Egg":
case "EnderPearl":
case "ExperienceBottle":
case "Potion":
case "Trident":
metaClassName = "Thrown" + metaClassName;
break;
default:
break;
}
String packageName = metadata.get(metaClassName);
if (packageName == null) {
LOGGER.error("The Entity metadata for " + entity.get("id").getAsString() + " is not implemented!");
LOGGER.error("The package for " + metaClassName + "Meta has been automatically set to 'undefined'");
LOGGER.error("The import will be missing!");
packageName = "undefined";
}
entityClass.addEnumConstant(
entityName,
TypeSpec.anonymousClassBuilder(
"$T.from($S), $L, $L, $T::new, $T.$N",
namespaceIDClassName,
entity.get("id").getAsString(),
entity.get("width").getAsDouble(),
entity.get("height").getAsDouble(),
ClassName.get(packageName, metaClassName + "Meta"),
ClassName.get("net.minestom.server.entity", "EntitySpawnType"),
entity.get("packetType").getAsString().toUpperCase()
).build()
);
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.entity", entityClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,221 @@
package net.minestom.codegen.entity;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
import java.util.List;
public final class VillagerProfessionGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(VillagerProfessionGenerator.class);
private final File villagerProfessionsFile;
private final File outputFolder;
public VillagerProfessionGenerator(@NotNull File villagerProfessionsFile, @NotNull File outputFolder) {
this.villagerProfessionsFile = villagerProfessionsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!villagerProfessionsFile.exists()) {
LOGGER.error("Failed to find villager_professions.json.");
LOGGER.error("Stopped code generation for villager professions.");
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 rawVillagerProfessionDataClassName = ClassName.get("net.minestom.server.raw_data", "RawVillagerProfessionData");
ClassName registryClassName = ClassName.get("net.minestom.server.registry", "Registry");
JsonArray villagerProfessions;
try {
villagerProfessions = GSON.fromJson(new JsonReader(new FileReader(villagerProfessionsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find villager_professions.json.");
LOGGER.error("Stopped code generation for villager professions.");
return;
}
ClassName villagerProfessionClassName = ClassName.get("net.minestom.server.entity.metadata.villager", "VillagerProfession");
// Particle
TypeSpec.Builder villagerProfessionClass = TypeSpec.classBuilder(villagerProfessionClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
villagerProfessionClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
villagerProfessionClass.addField(
FieldSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData")
.addModifiers(Modifier.PRIVATE, Modifier.VOLATILE)
.addAnnotation(NotNull.class)
.build()
);
villagerProfessionClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addParameter(ParameterSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("this.villagerProfessionData = villagerProfessionData")
.addModifiers(Modifier.PROTECTED)
.build()
);
// Override key method (adventure)
villagerProfessionClass.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
villagerProfessionClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getVillagerProfessionData method
villagerProfessionClass.addMethod(
MethodSpec.methodBuilder("getVillagerProfessionData")
.returns(rawVillagerProfessionDataClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.villagerProfessionData")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.build()
);
// setVillagerProfessionData method
villagerProfessionClass.addMethod(
MethodSpec.methodBuilder("setVillagerProfessionData")
.addParameter(ParameterSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData").addAnnotation(NotNull.class).build())
.addStatement("this.villagerProfessionData = villagerProfessionData")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.build()
);
// getNumericalId
villagerProfessionClass.addMethod(
MethodSpec.methodBuilder("getNumericalId")
.returns(TypeName.INT)
.addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.getId(this)", registryClassName)
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
villagerProfessionClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(villagerProfessionClassName)
.addAnnotation(Nullable.class)
.addParameter(TypeName.INT, "id")
.addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.get((short) id)", registryClassName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
// fromId Method
villagerProfessionClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(villagerProfessionClassName)
.addAnnotation(NotNull.class)
.addParameter(ClassName.get("net.kyori.adventure.key", "Key"), "id")
.addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.get(id)", registryClassName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
// toString method
villagerProfessionClass.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()
);
// values method
villagerProfessionClass.addMethod(
MethodSpec.methodBuilder("values")
.addAnnotation(NotNull.class)
.returns(ParameterizedTypeName.get(ClassName.get(List.class), villagerProfessionClassName))
.addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.values()", registryClassName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
CodeBlock.Builder staticBlock = CodeBlock.builder();
// Use data
for (JsonElement vp : villagerProfessions) {
JsonObject villagerProfession = vp.getAsJsonObject();
String villagerProfessionName = villagerProfession.get("name").getAsString();
JsonElement workSound = villagerProfession.get("workSound");
if (workSound == null) {
villagerProfessionClass.addField(
FieldSpec.builder(
villagerProfessionClassName,
villagerProfessionName
).initializer(
"new $T($T.from($S), new $T(() -> null))",
villagerProfessionClassName,
namespaceIDClassName,
villagerProfession.get("id").getAsString(),
rawVillagerProfessionDataClassName
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
);
} else {
villagerProfessionClass.addField(
FieldSpec.builder(
villagerProfessionClassName,
villagerProfessionName
).initializer(
"new $T($T.from($S), new $T(() -> $T.SOUND_EVENT_REGISTRY.get($S)))",
villagerProfessionClassName,
namespaceIDClassName,
villagerProfession.get("id").getAsString(),
rawVillagerProfessionDataClassName,
registryClassName,
workSound.getAsString()
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
);
}
// Add to static init.
staticBlock.addStatement("$T.VILLAGER_PROFESSION_REGISTRY.register($N)", registryClassName, villagerProfessionName);
}
villagerProfessionClass.addStaticBlock(staticBlock.build());
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.entity.metadata.villager", villagerProfessionClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,173 @@
package net.minestom.codegen.entity;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
import java.util.List;
public final class VillagerTypeGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(VillagerTypeGenerator.class);
private final File villagerTypesFile;
private final File outputFolder;
public VillagerTypeGenerator(@NotNull File villagerTypesFile, @NotNull File outputFolder) {
this.villagerTypesFile = villagerTypesFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!villagerTypesFile.exists()) {
LOGGER.error("Failed to find villager_types.json.");
LOGGER.error("Stopped code generation for villager types.");
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 registryClassName = ClassName.get("net.minestom.server.registry", "Registry");
JsonArray villagerTypes;
try {
villagerTypes = GSON.fromJson(new JsonReader(new FileReader(villagerTypesFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find villager_types.json.");
LOGGER.error("Stopped code generation for villager types.");
return;
}
ClassName villagerTypeClassName = ClassName.get("net.minestom.server.entity.metadata.villager", "VillagerType");
// Particle
TypeSpec.Builder villagerTypeClass = TypeSpec.classBuilder(villagerTypeClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
villagerTypeClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
villagerTypeClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addModifiers(Modifier.PROTECTED)
.build()
);
// Override key method (adventure)
villagerTypeClass.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
villagerTypeClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNumericalId
villagerTypeClass.addMethod(
MethodSpec.methodBuilder("getNumericalId")
.returns(TypeName.INT)
.addStatement("return $T.VILLAGER_TYPE_REGISTRY.getId(this)", registryClassName)
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
villagerTypeClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(villagerTypeClassName)
.addAnnotation(Nullable.class)
.addParameter(TypeName.INT, "id")
.addStatement("return $T.VILLAGER_TYPE_REGISTRY.get((short) id)", registryClassName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
// fromId Method
villagerTypeClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(villagerTypeClassName)
.addAnnotation(NotNull.class)
.addParameter(ClassName.get("net.kyori.adventure.key", "Key"), "id")
.addStatement("return $T.VILLAGER_TYPE_REGISTRY.get(id)", registryClassName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
// toString method
villagerTypeClass.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()
);
// values method
villagerTypeClass.addMethod(
MethodSpec.methodBuilder("values")
.addAnnotation(NotNull.class)
.returns(ParameterizedTypeName.get(ClassName.get(List.class), villagerTypeClassName))
.addStatement("return $T.VILLAGER_TYPE_REGISTRY.values()", registryClassName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
CodeBlock.Builder staticBlock = CodeBlock.builder();
// Use data
for (JsonElement vp : villagerTypes) {
JsonObject villagerProfession = vp.getAsJsonObject();
String villagerProfessionName = villagerProfession.get("name").getAsString();
villagerTypeClass.addField(
FieldSpec.builder(
villagerTypeClassName,
villagerProfessionName
).initializer(
"new $T($T.from($S))",
villagerTypeClassName,
namespaceIDClassName,
villagerProfession.get("id").getAsString()
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
);
// Add to static init.
staticBlock.addStatement("$T.VILLAGER_TYPE_REGISTRY.register($N)", registryClassName, villagerProfessionName);
}
villagerTypeClass.addStaticBlock(staticBlock.build());
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.entity.metadata.villager", villagerTypeClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,157 @@
package net.minestom.codegen.fluid;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
public final class FluidGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(FluidGenerator.class);
private final File fluidsFile;
private final File outputFolder;
public FluidGenerator(@NotNull File fluidsFile, @NotNull File outputFolder) {
this.fluidsFile = fluidsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!fluidsFile.exists()) {
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");
JsonArray fluids;
try {
fluids = GSON.fromJson(new JsonReader(new FileReader(fluidsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find fluids.json.");
LOGGER.error("Stopped code generation for fluids.");
return;
}
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
for (JsonElement f : fluids) {
JsonObject fluid = f.getAsJsonObject();
String fluidName = fluid.get("name").getAsString();
fluidClass.addEnumConstant(fluidName, TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIDClassName,
fluid.get("id").getAsString()
).build()
);
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.fluid", fluidClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,156 @@
package net.minestom.codegen.item;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
public final class EnchantmentGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(EnchantmentGenerator.class);
private final File enchantmentsFile;
private final File outputFolder;
public EnchantmentGenerator(@NotNull File enchantmentsFile, @NotNull File outputFolder) {
this.enchantmentsFile = enchantmentsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!enchantmentsFile.exists()) {
LOGGER.error("Failed to find enchantments.json.");
LOGGER.error("Stopped code generation for enchantments.");
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");
JsonArray enchantments;
try {
enchantments = GSON.fromJson(new JsonReader(new FileReader(enchantmentsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find enchantments.json.");
LOGGER.error("Stopped code generation for enchantments.");
return;
}
ClassName enchantmentClassName = ClassName.get("net.minestom.server.item", "Enchantment");
// Enchantment
TypeSpec.Builder enchantmentClass = TypeSpec.enumBuilder(enchantmentClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
enchantmentClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
// static field
enchantmentClass.addField(
FieldSpec.builder(ArrayTypeName.of(enchantmentClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
enchantmentClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("$T.enchantments.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
enchantmentClass.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
enchantmentClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
enchantmentClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
enchantmentClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(enchantmentClassName)
.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()
);
// toString method
enchantmentClass.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()
);
// Use data
for (JsonElement e : enchantments) {
JsonObject enchantment = e.getAsJsonObject();
String enchantmentName = enchantment.get("name").getAsString();
enchantmentClass.addEnumConstant(enchantmentName, TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIDClassName,
enchantment.get("id").getAsString()
).build()
);
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.item", enchantmentClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,351 @@
package net.minestom.codegen.item;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
import java.util.function.Supplier;
public final class MaterialGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(MaterialGenerator.class);
private final File itemsFile;
private final File outputFolder;
public MaterialGenerator(@NotNull File itemsFile, @NotNull File outputFolder) {
this.itemsFile = itemsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!itemsFile.exists()) {
LOGGER.error("Failed to find items.json.");
LOGGER.error("Stopped code generation for items.");
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");
ClassName blockCN = ClassName.get("net.minestom.server.instance.block", "Block");
ParameterizedTypeName blocksCNSupplier = ParameterizedTypeName.get(ClassName.get(Supplier.class), blockCN);
JsonArray items;
try {
items = GSON.fromJson(new JsonReader(new FileReader(itemsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find items.json.");
LOGGER.error("Stopped code generation for items.");
return;
}
ClassName itemClassName = ClassName.get("net.minestom.server.item", "Material");
// Item
TypeSpec.Builder itemClass = TypeSpec.enumBuilder(itemClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
itemClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
itemClass.addField(
FieldSpec.builder(TypeName.BYTE, "maxDefaultStackSize")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
itemClass.addField(
FieldSpec.builder(blocksCNSupplier, "correspondingBlockSupplier")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
);
// static field
itemClass.addField(
FieldSpec.builder(ArrayTypeName.of(itemClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
itemClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addParameter(TypeName.BYTE, "maxDefaultStackSize")
.addParameter(ParameterSpec.builder(blocksCNSupplier, "correspondingBlockSupplier").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("this.maxDefaultStackSize = maxDefaultStackSize")
.addStatement("this.correspondingBlockSupplier = correspondingBlockSupplier")
.addStatement("$T.materials.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
itemClass.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
itemClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
itemClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getName method
itemClass.addMethod(
MethodSpec.methodBuilder("getName")
.addAnnotation(NotNull.class)
.returns(ClassName.get(String.class))
.addStatement("return this.id.asString()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getMaxDefaultStackSize
itemClass.addMethod(
MethodSpec.methodBuilder("getMaxDefaultStackSize")
.returns(TypeName.BYTE)
.addStatement("return this.maxDefaultStackSize")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
itemClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(itemClassName)
.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()
);
// isFood method
itemClass.addMethod(
MethodSpec.methodBuilder("isFood")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// hasState method
itemClass.addMethod(
MethodSpec.methodBuilder("hasState")
.returns(TypeName.BOOLEAN)
.beginControlFlow("if (this == BOW || this == TRIDENT || this == CROSSBOW || this == SHIELD)")
.addStatement("return true")
.nextControlFlow("else")
.addStatement("return isFood()")
.endControlFlow()
.addModifiers(Modifier.PUBLIC)
.build()
);
// isBlock method
itemClass.addMethod(
MethodSpec.methodBuilder("isBlock")
.returns(TypeName.BOOLEAN)
.addStatement(
"return this.correspondingBlockSupplier.get() != null && this.correspondingBlockSupplier.get() != $T.AIR",
blockCN
)
.addModifiers(Modifier.PUBLIC)
.build()
);
// isArmor method
itemClass.addMethod(
MethodSpec.methodBuilder("isArmor")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isHelmet method
itemClass.addMethod(
MethodSpec.methodBuilder("isHelmet")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isChestplate method
itemClass.addMethod(
MethodSpec.methodBuilder("isChestplate")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isLeggings method
itemClass.addMethod(
MethodSpec.methodBuilder("isLeggings")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// isBoots method
itemClass.addMethod(
MethodSpec.methodBuilder("isBoots")
.returns(TypeName.BOOLEAN)
.addStatement("return false")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getBlock method
itemClass.addMethod(
MethodSpec.methodBuilder("getBlock")
.addAnnotation(Nullable.class)
.returns(blockCN)
.addStatement("return this.correspondingBlockSupplier.get()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// toString method
itemClass.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()
);
// Use data
for (JsonElement i : items) {
JsonObject item = i.getAsJsonObject();
String itemName = item.get("name").getAsString();
TypeSpec.Builder enumConst;
if (!(item.get("blockId").getAsString().equals("minecraft:air"))) {
enumConst = TypeSpec.anonymousClassBuilder(
"$T.from($S), (byte) $L, () -> $T.getBlock($S)",
namespaceIDClassName,
item.get("id").getAsString(),
item.get("maxStackSize").getAsInt(),
// Supplier
registriesClassName,
item.get("blockId").getAsString()
);
} else {
enumConst = TypeSpec.anonymousClassBuilder(
"$T.from($S), (byte) $L, () -> null",
namespaceIDClassName,
item.get("id").getAsString(),
item.get("maxStackSize").getAsInt()
);
}
if (item.get("edible").getAsBoolean()) {
enumConst.addMethod(
MethodSpec.methodBuilder("isFood")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
}
if (item.get("armorProperties") != null) {
JsonObject ap = item.get("armorProperties").getAsJsonObject();
enumConst.addMethod(
MethodSpec.methodBuilder("isArmor")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
if (ap.get("slot") != null) {
switch (ap.get("slot").getAsString()) {
case "head": {
enumConst.addMethod(
MethodSpec.methodBuilder("isHelmet")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
break;
}
case "chest": {
enumConst.addMethod(
MethodSpec.methodBuilder("isChestplate")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
break;
}
case "legs": {
enumConst.addMethod(
MethodSpec.methodBuilder("isLeggings")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
break;
}
case "feet": {
enumConst.addMethod(
MethodSpec.methodBuilder("isBoots")
.returns(TypeName.BOOLEAN)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addStatement("return true")
.build()
);
break;
}
}
}
}
itemClass.addEnumConstant(itemName, enumConst.build());
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.item", itemClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,155 @@
package net.minestom.codegen.particle;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
public final class ParticleGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(ParticleGenerator.class);
private final File particlesFile;
private final File outputFolder;
public ParticleGenerator(@NotNull File particlesFile, @NotNull File outputFolder) {
this.particlesFile = particlesFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!particlesFile.exists()) {
LOGGER.error("Failed to find particles.json.");
LOGGER.error("Stopped code generation for particles.");
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");
JsonArray particles;
try {
particles = GSON.fromJson(new JsonReader(new FileReader(particlesFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find particles.json.");
LOGGER.error("Stopped code generation for particles.");
return;
}
ClassName particleClassName = ClassName.get("net.minestom.server.particle", "Particle");
// Particle
TypeSpec.Builder particleClass = TypeSpec.enumBuilder(particleClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
particleClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
// static field
particleClass.addField(
FieldSpec.builder(ArrayTypeName.of(particleClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
particleClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("$T.particles.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
particleClass.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
particleClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
particleClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
particleClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(particleClassName)
.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()
);
// toString method
particleClass.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()
);
// Use data
for (JsonElement p : particles) {
JsonObject particle = p.getAsJsonObject();
String particleName = particle.get("name").getAsString();
particleClass.addEnumConstant(particleName, TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIDClassName,
particle.get("id").getAsString()
).build());
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.particle", particleClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,156 @@
package net.minestom.codegen.potion;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
public final class PotionEffectGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(PotionEffectGenerator.class);
private final File potionEffectsFile;
private final File outputFolder;
public PotionEffectGenerator(@NotNull File potionEffectsFile, @NotNull File outputFolder) {
this.potionEffectsFile = potionEffectsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!potionEffectsFile.exists()) {
LOGGER.error("Failed to find potionEffects.json.");
LOGGER.error("Stopped code generation for potion effects.");
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");
JsonArray potionEffects;
try {
potionEffects = GSON.fromJson(new JsonReader(new FileReader(potionEffectsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find potionEffects.json.");
LOGGER.error("Stopped code generation for potion effects.");
return;
}
ClassName potionEffectClassName = ClassName.get("net.minestom.server.potion", "PotionEffect");
// Particle
TypeSpec.Builder potionEffectClass = TypeSpec.enumBuilder(potionEffectClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
potionEffectClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
// static field
potionEffectClass.addField(
FieldSpec.builder(ArrayTypeName.of(potionEffectClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
potionEffectClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("$T.potionEffects.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
potionEffectClass.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
potionEffectClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
potionEffectClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
potionEffectClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(potionEffectClassName)
.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()
);
// toString method
potionEffectClass.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()
);
// Use data
for (JsonElement pe : potionEffects) {
JsonObject potionEffect = pe.getAsJsonObject();
String potionEffectName = potionEffect.get("name").getAsString();
potionEffectClass.addEnumConstant(potionEffectName, TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIDClassName,
potionEffect.get("id").getAsString()
).build()
);
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.potion", potionEffectClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,156 @@
package net.minestom.codegen.potion;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
public final class PotionTypeGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(PotionTypeGenerator.class);
private final File potionsFile;
private final File outputFolder;
public PotionTypeGenerator(@NotNull File potionsFile, @NotNull File outputFolder) {
this.potionsFile = potionsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!potionsFile.exists()) {
LOGGER.error("Failed to find potions.json.");
LOGGER.error("Stopped code generation for potions.");
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");
JsonArray potions;
try {
potions = GSON.fromJson(new JsonReader(new FileReader(potionsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find potions.json.");
LOGGER.error("Stopped code generation for potions.");
return;
}
ClassName potionTypeClassName = ClassName.get("net.minestom.server.potion", "PotionType");
// Particle
TypeSpec.Builder potionTypeClass = TypeSpec.enumBuilder(potionTypeClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
potionTypeClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
// static field
potionTypeClass.addField(
FieldSpec.builder(ArrayTypeName.of(potionTypeClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
potionTypeClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("$T.potionTypes.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
potionTypeClass.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
potionTypeClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
potionTypeClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
potionTypeClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(potionTypeClassName)
.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()
);
// toString method
potionTypeClass.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()
);
// Use data
for (JsonElement p : potions) {
JsonObject potion = p.getAsJsonObject();
String potionName = potion.get("name").getAsString();
potionTypeClass.addEnumConstant(potionName, TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIDClassName,
potion.get("id").getAsString()
).build()
);
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.potion", potionTypeClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,155 @@
package net.minestom.codegen.sound;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
public final class SoundEventGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(SoundEventGenerator.class);
private final File soundsFile;
private final File outputFolder;
public SoundEventGenerator(@NotNull File itemsFile, @NotNull File outputFolder) {
this.soundsFile = itemsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!soundsFile.exists()) {
LOGGER.error("Failed to find sounds.json.");
LOGGER.error("Stopped code generation for sounds.");
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");
JsonArray sounds;
try {
sounds = GSON.fromJson(new JsonReader(new FileReader(soundsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find sounds.json.");
LOGGER.error("Stopped code generation for sounds.");
return;
}
ClassName soundClassName = ClassName.get("net.minestom.server.sound", "SoundEvent");
// Sound
TypeSpec.Builder soundClass = TypeSpec.enumBuilder(soundClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addSuperinterface(ClassName.get("net.kyori.adventure.sound", "Sound", "Type"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
soundClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
// static field
soundClass.addField(
FieldSpec.builder(ArrayTypeName.of(soundClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
soundClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("$T.soundEvents.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
soundClass.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
soundClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
soundClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
soundClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(soundClassName)
.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()
);
// toString method
soundClass.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()
);
// Use data
for (JsonElement s : sounds) {
JsonObject sound = s.getAsJsonObject();
String soundName = sound.get("name").getAsString();
soundClass.addEnumConstant(soundName, TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIDClassName,
sound.get("id").getAsString()
).build()
);
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.sound", soundClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -0,0 +1,156 @@
package net.minestom.codegen.statistics;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
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.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
public final class StatisticGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(StatisticGenerator.class);
private final File statisticsFile;
private final File outputFolder;
public StatisticGenerator(@NotNull File statisticsFile, @NotNull File outputFolder) {
this.statisticsFile = statisticsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!statisticsFile.exists()) {
LOGGER.error("Failed to find statistics.json.");
LOGGER.error("Stopped code generation for statistics.");
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");
JsonArray statistics;
try {
statistics = GSON.fromJson(new JsonReader(new FileReader(statisticsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find statistics.json.");
LOGGER.error("Stopped code generation for statistics.");
return;
}
ClassName statisticClassName = ClassName.get("net.minestom.server.statistic", "StatisticType");
// Particle
TypeSpec.Builder statisticClass = TypeSpec.enumBuilder(statisticClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
statisticClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
// static field
statisticClass.addField(
FieldSpec.builder(ArrayTypeName.of(statisticClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
statisticClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("$T.statisticTypes.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
statisticClass.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
statisticClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
statisticClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
statisticClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(statisticClassName)
.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()
);
// toString method
statisticClass.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()
);
// Use data
for (JsonElement s : statistics) {
JsonObject statistic = s.getAsJsonObject();
String statisticName = statistic.get("name").getAsString();
statisticClass.addEnumConstant(statisticName, TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIDClassName,
statistic.get("id").getAsString()
).build()
);
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.statistic", statisticClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

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

View File

@ -1,3 +1,5 @@
# Update with every release
mcVersion = 1.16.5
asmVersion=9.0
mixinVersion=0.8.1
hephaistosVersion=v1.1.8

@ -1 +0,0 @@
Subproject commit 2b25cb297bdad56a0673ab54f2a631a9808ea3b6

View File

@ -1,2 +1,2 @@
rootProject.name = 'Minestom'
include 'code-generators'

View File

@ -1,11 +1,31 @@
package net.minestom.server.entity;
import java.util.function.BiFunction;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.metadata.ambient.BatMeta;
import net.minestom.server.entity.metadata.animal.*;
import net.minestom.server.entity.metadata.animal.BeeMeta;
import net.minestom.server.entity.metadata.animal.ChickenMeta;
import net.minestom.server.entity.metadata.animal.CowMeta;
import net.minestom.server.entity.metadata.animal.DonkeyMeta;
import net.minestom.server.entity.metadata.animal.FoxMeta;
import net.minestom.server.entity.metadata.animal.HoglinMeta;
import net.minestom.server.entity.metadata.animal.HorseMeta;
import net.minestom.server.entity.metadata.animal.LlamaMeta;
import net.minestom.server.entity.metadata.animal.MooshroomMeta;
import net.minestom.server.entity.metadata.animal.MuleMeta;
import net.minestom.server.entity.metadata.animal.OcelotMeta;
import net.minestom.server.entity.metadata.animal.PandaMeta;
import net.minestom.server.entity.metadata.animal.PigMeta;
import net.minestom.server.entity.metadata.animal.PolarBearMeta;
import net.minestom.server.entity.metadata.animal.RabbitMeta;
import net.minestom.server.entity.metadata.animal.SheepMeta;
import net.minestom.server.entity.metadata.animal.SkeletonHorseMeta;
import net.minestom.server.entity.metadata.animal.StriderMeta;
import net.minestom.server.entity.metadata.animal.TurtleMeta;
import net.minestom.server.entity.metadata.animal.ZombieHorseMeta;
import net.minestom.server.entity.metadata.animal.tameable.CatMeta;
import net.minestom.server.entity.metadata.animal.tameable.ParrotMeta;
import net.minestom.server.entity.metadata.animal.tameable.WolfMeta;
@ -17,15 +37,73 @@ import net.minestom.server.entity.metadata.flying.PhantomMeta;
import net.minestom.server.entity.metadata.golem.IronGolemMeta;
import net.minestom.server.entity.metadata.golem.ShulkerMeta;
import net.minestom.server.entity.metadata.golem.SnowGolemMeta;
import net.minestom.server.entity.metadata.item.*;
import net.minestom.server.entity.metadata.minecart.*;
import net.minestom.server.entity.metadata.monster.*;
import net.minestom.server.entity.metadata.monster.raider.*;
import net.minestom.server.entity.metadata.item.EyeOfEnderMeta;
import net.minestom.server.entity.metadata.item.FireballMeta;
import net.minestom.server.entity.metadata.item.ItemEntityMeta;
import net.minestom.server.entity.metadata.item.SmallFireballMeta;
import net.minestom.server.entity.metadata.item.SnowballMeta;
import net.minestom.server.entity.metadata.item.ThrownEggMeta;
import net.minestom.server.entity.metadata.item.ThrownEnderPearlMeta;
import net.minestom.server.entity.metadata.item.ThrownExperienceBottleMeta;
import net.minestom.server.entity.metadata.item.ThrownPotionMeta;
import net.minestom.server.entity.metadata.minecart.ChestMinecartMeta;
import net.minestom.server.entity.metadata.minecart.CommandBlockMinecartMeta;
import net.minestom.server.entity.metadata.minecart.FurnaceMinecartMeta;
import net.minestom.server.entity.metadata.minecart.HopperMinecartMeta;
import net.minestom.server.entity.metadata.minecart.MinecartMeta;
import net.minestom.server.entity.metadata.minecart.SpawnerMinecartMeta;
import net.minestom.server.entity.metadata.minecart.TntMinecartMeta;
import net.minestom.server.entity.metadata.monster.BlazeMeta;
import net.minestom.server.entity.metadata.monster.CaveSpiderMeta;
import net.minestom.server.entity.metadata.monster.CreeperMeta;
import net.minestom.server.entity.metadata.monster.ElderGuardianMeta;
import net.minestom.server.entity.metadata.monster.EndermanMeta;
import net.minestom.server.entity.metadata.monster.EndermiteMeta;
import net.minestom.server.entity.metadata.monster.GiantMeta;
import net.minestom.server.entity.metadata.monster.GuardianMeta;
import net.minestom.server.entity.metadata.monster.PiglinBruteMeta;
import net.minestom.server.entity.metadata.monster.PiglinMeta;
import net.minestom.server.entity.metadata.monster.SilverfishMeta;
import net.minestom.server.entity.metadata.monster.SpiderMeta;
import net.minestom.server.entity.metadata.monster.VexMeta;
import net.minestom.server.entity.metadata.monster.WitherMeta;
import net.minestom.server.entity.metadata.monster.ZoglinMeta;
import net.minestom.server.entity.metadata.monster.raider.EvokerMeta;
import net.minestom.server.entity.metadata.monster.raider.IllusionerMeta;
import net.minestom.server.entity.metadata.monster.raider.PillagerMeta;
import net.minestom.server.entity.metadata.monster.raider.RavagerMeta;
import net.minestom.server.entity.metadata.monster.raider.VindicatorMeta;
import net.minestom.server.entity.metadata.monster.raider.WitchMeta;
import net.minestom.server.entity.metadata.monster.skeleton.SkeletonMeta;
import net.minestom.server.entity.metadata.monster.skeleton.StrayMeta;
import net.minestom.server.entity.metadata.monster.skeleton.WitherSkeletonMeta;
import net.minestom.server.entity.metadata.monster.zombie.*;
import net.minestom.server.entity.metadata.other.*;
import net.minestom.server.entity.metadata.monster.zombie.DrownedMeta;
import net.minestom.server.entity.metadata.monster.zombie.HuskMeta;
import net.minestom.server.entity.metadata.monster.zombie.ZombieMeta;
import net.minestom.server.entity.metadata.monster.zombie.ZombieVillagerMeta;
import net.minestom.server.entity.metadata.monster.zombie.ZombifiedPiglinMeta;
import net.minestom.server.entity.metadata.other.AreaEffectCloudMeta;
import net.minestom.server.entity.metadata.other.ArmorStandMeta;
import net.minestom.server.entity.metadata.other.BoatMeta;
import net.minestom.server.entity.metadata.other.DragonFireballMeta;
import net.minestom.server.entity.metadata.other.EndCrystalMeta;
import net.minestom.server.entity.metadata.other.EnderDragonMeta;
import net.minestom.server.entity.metadata.other.EvokerFangsMeta;
import net.minestom.server.entity.metadata.other.ExperienceOrbMeta;
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
import net.minestom.server.entity.metadata.other.FireworkRocketMeta;
import net.minestom.server.entity.metadata.other.FishingHookMeta;
import net.minestom.server.entity.metadata.other.ItemFrameMeta;
import net.minestom.server.entity.metadata.other.LeashKnotMeta;
import net.minestom.server.entity.metadata.other.LightningBoltMeta;
import net.minestom.server.entity.metadata.other.LlamaSpitMeta;
import net.minestom.server.entity.metadata.other.MagmaCubeMeta;
import net.minestom.server.entity.metadata.other.PaintingMeta;
import net.minestom.server.entity.metadata.other.PrimedTntMeta;
import net.minestom.server.entity.metadata.other.ShulkerBulletMeta;
import net.minestom.server.entity.metadata.other.SlimeMeta;
import net.minestom.server.entity.metadata.other.TraderLlamaMeta;
import net.minestom.server.entity.metadata.other.WitherSkullMeta;
import net.minestom.server.entity.metadata.villager.VillagerMeta;
import net.minestom.server.entity.metadata.villager.WanderingTraderMeta;
import net.minestom.server.entity.metadata.water.DolphinMeta;
@ -37,236 +115,232 @@ import net.minestom.server.entity.metadata.water.fish.TropicalFishMeta;
import net.minestom.server.registry.Registries;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import java.util.function.BiFunction;
import org.jetbrains.annotations.Nullable;
/**
* //==============================
* // AUTOGENERATED BY EnumGenerator
* //==============================
* AUTOGENERATED by EntityTypeGenerator
*/
@SuppressWarnings({"deprecation"})
public enum EntityType implements Keyed {
AREA_EFFECT_CLOUD("minecraft:area_effect_cloud", 6.0, 0.5, AreaEffectCloudMeta::new, EntitySpawnType.BASE),
AREA_EFFECT_CLOUD(NamespaceID.from("minecraft:area_effect_cloud"), 6.0, 0.5, AreaEffectCloudMeta::new, EntitySpawnType.BASE),
ARMOR_STAND("minecraft:armor_stand", 0.5, 1.975, ArmorStandMeta::new, EntitySpawnType.LIVING),
ARMOR_STAND(NamespaceID.from("minecraft:armor_stand"), 0.5, 1.975, ArmorStandMeta::new, EntitySpawnType.LIVING),
ARROW("minecraft:arrow", 0.5, 0.5, ArrowMeta::new, EntitySpawnType.BASE),
ARROW(NamespaceID.from("minecraft:arrow"), 0.5, 0.5, ArrowMeta::new, EntitySpawnType.BASE),
BAT("minecraft:bat", 0.5, 0.9, BatMeta::new, EntitySpawnType.LIVING),
BAT(NamespaceID.from("minecraft:bat"), 0.5, 0.9, BatMeta::new, EntitySpawnType.LIVING),
BEE("minecraft:bee", 0.7, 0.6, BeeMeta::new, EntitySpawnType.LIVING),
BEE(NamespaceID.from("minecraft:bee"), 0.7, 0.6, BeeMeta::new, EntitySpawnType.LIVING),
BLAZE("minecraft:blaze", 0.6, 1.8, BlazeMeta::new, EntitySpawnType.LIVING),
BLAZE(NamespaceID.from("minecraft:blaze"), 0.6, 1.8, BlazeMeta::new, EntitySpawnType.LIVING),
BOAT("minecraft:boat", 1.375, 0.5625, BoatMeta::new, EntitySpawnType.BASE),
BOAT(NamespaceID.from("minecraft:boat"), 1.375, 0.5625, BoatMeta::new, EntitySpawnType.BASE),
CAT("minecraft:cat", 0.6, 0.7, CatMeta::new, EntitySpawnType.LIVING),
CAT(NamespaceID.from("minecraft:cat"), 0.6, 0.7, CatMeta::new, EntitySpawnType.LIVING),
CAVE_SPIDER("minecraft:cave_spider", 0.7, 0.5, CaveSpiderMeta::new, EntitySpawnType.LIVING),
CAVE_SPIDER(NamespaceID.from("minecraft:cave_spider"), 0.7, 0.5, CaveSpiderMeta::new, EntitySpawnType.LIVING),
CHICKEN("minecraft:chicken", 0.4, 0.7, ChickenMeta::new, EntitySpawnType.LIVING),
CHICKEN(NamespaceID.from("minecraft:chicken"), 0.4, 0.7, ChickenMeta::new, EntitySpawnType.LIVING),
COD("minecraft:cod", 0.5, 0.3, CodMeta::new, EntitySpawnType.LIVING),
COD(NamespaceID.from("minecraft:cod"), 0.5, 0.3, CodMeta::new, EntitySpawnType.LIVING),
COW("minecraft:cow", 0.9, 1.4, CowMeta::new, EntitySpawnType.LIVING),
COW(NamespaceID.from("minecraft:cow"), 0.9, 1.4, CowMeta::new, EntitySpawnType.LIVING),
CREEPER("minecraft:creeper", 0.6, 1.7, CreeperMeta::new, EntitySpawnType.LIVING),
CREEPER(NamespaceID.from("minecraft:creeper"), 0.6, 1.7, CreeperMeta::new, EntitySpawnType.LIVING),
DOLPHIN("minecraft:dolphin", 0.9, 0.6, DolphinMeta::new, EntitySpawnType.LIVING),
DOLPHIN(NamespaceID.from("minecraft:dolphin"), 0.9, 0.6, DolphinMeta::new, EntitySpawnType.LIVING),
DONKEY("minecraft:donkey", 1.39648, 1.5, DonkeyMeta::new, EntitySpawnType.LIVING),
DONKEY(NamespaceID.from("minecraft:donkey"), 1.3964844, 1.5, DonkeyMeta::new, EntitySpawnType.LIVING),
DRAGON_FIREBALL("minecraft:dragon_fireball", 1.0, 1.0, DragonFireballMeta::new, EntitySpawnType.BASE),
DRAGON_FIREBALL(NamespaceID.from("minecraft:dragon_fireball"), 1.0, 1.0, DragonFireballMeta::new, EntitySpawnType.BASE),
DROWNED("minecraft:drowned", 0.6, 1.95, DrownedMeta::new, EntitySpawnType.LIVING),
DROWNED(NamespaceID.from("minecraft:drowned"), 0.6, 1.95, DrownedMeta::new, EntitySpawnType.LIVING),
ELDER_GUARDIAN("minecraft:elder_guardian", 1.9975, 1.9975, ElderGuardianMeta::new, EntitySpawnType.LIVING),
ELDER_GUARDIAN(NamespaceID.from("minecraft:elder_guardian"), 1.9975, 1.9975, ElderGuardianMeta::new, EntitySpawnType.LIVING),
END_CRYSTAL("minecraft:end_crystal", 2.0, 2.0, EndCrystalMeta::new, EntitySpawnType.BASE),
END_CRYSTAL(NamespaceID.from("minecraft:end_crystal"), 2.0, 2.0, EndCrystalMeta::new, EntitySpawnType.BASE),
ENDER_DRAGON("minecraft:ender_dragon", 16.0, 8.0, EnderDragonMeta::new, EntitySpawnType.LIVING),
ENDER_DRAGON(NamespaceID.from("minecraft:ender_dragon"), 16.0, 8.0, EnderDragonMeta::new, EntitySpawnType.LIVING),
ENDERMAN("minecraft:enderman", 0.6, 2.9, EndermanMeta::new, EntitySpawnType.LIVING),
ENDERMAN(NamespaceID.from("minecraft:enderman"), 0.6, 2.9, EndermanMeta::new, EntitySpawnType.LIVING),
ENDERMITE("minecraft:endermite", 0.4, 0.3, EndermiteMeta::new, EntitySpawnType.LIVING),
ENDERMITE(NamespaceID.from("minecraft:endermite"), 0.4, 0.3, EndermiteMeta::new, EntitySpawnType.LIVING),
EVOKER("minecraft:evoker", 0.6, 1.95, EvokerMeta::new, EntitySpawnType.LIVING),
EVOKER(NamespaceID.from("minecraft:evoker"), 0.6, 1.95, EvokerMeta::new, EntitySpawnType.LIVING),
EVOKER_FANGS("minecraft:evoker_fangs", 0.5, 0.8, EvokerFangsMeta::new, EntitySpawnType.BASE),
EVOKER_FANGS(NamespaceID.from("minecraft:evoker_fangs"), 0.5, 0.8, EvokerFangsMeta::new, EntitySpawnType.BASE),
EXPERIENCE_ORB("minecraft:experience_orb", 0.5, 0.5, ExperienceOrbMeta::new, EntitySpawnType.EXPERIENCE_ORB),
EXPERIENCE_ORB(NamespaceID.from("minecraft:experience_orb"), 0.5, 0.5, ExperienceOrbMeta::new, EntitySpawnType.EXPERIENCE_ORB),
EYE_OF_ENDER("minecraft:eye_of_ender", 0.25, 0.25, EyeOfEnderMeta::new, EntitySpawnType.BASE),
EYE_OF_ENDER(NamespaceID.from("minecraft:eye_of_ender"), 0.25, 0.25, EyeOfEnderMeta::new, EntitySpawnType.BASE),
FALLING_BLOCK("minecraft:falling_block", 0.98, 0.98, FallingBlockMeta::new, EntitySpawnType.BASE),
FALLING_BLOCK(NamespaceID.from("minecraft:falling_block"), 0.98, 0.98, FallingBlockMeta::new, EntitySpawnType.BASE),
FIREWORK_ROCKET("minecraft:firework_rocket", 0.25, 0.25, FireworkRocketMeta::new, EntitySpawnType.BASE),
FIREWORK_ROCKET(NamespaceID.from("minecraft:firework_rocket"), 0.25, 0.25, FireworkRocketMeta::new, EntitySpawnType.BASE),
FOX("minecraft:fox", 0.6, 0.7, FoxMeta::new, EntitySpawnType.LIVING),
FOX(NamespaceID.from("minecraft:fox"), 0.6, 0.7, FoxMeta::new, EntitySpawnType.LIVING),
GHAST("minecraft:ghast", 4.0, 4.0, GhastMeta::new, EntitySpawnType.LIVING),
GHAST(NamespaceID.from("minecraft:ghast"), 4.0, 4.0, GhastMeta::new, EntitySpawnType.LIVING),
GIANT("minecraft:giant", 3.6, 12.0, GiantMeta::new, EntitySpawnType.LIVING),
GIANT(NamespaceID.from("minecraft:giant"), 3.6, 12.0, GiantMeta::new, EntitySpawnType.LIVING),
GUARDIAN("minecraft:guardian", 0.85, 0.85, GuardianMeta::new, EntitySpawnType.LIVING),
GUARDIAN(NamespaceID.from("minecraft:guardian"), 0.85, 0.85, GuardianMeta::new, EntitySpawnType.LIVING),
HOGLIN("minecraft:hoglin", 1.39648, 1.4, HoglinMeta::new, EntitySpawnType.LIVING),
HOGLIN(NamespaceID.from("minecraft:hoglin"), 1.3964844, 1.4, HoglinMeta::new, EntitySpawnType.LIVING),
HORSE("minecraft:horse", 1.39648, 1.6, HorseMeta::new, EntitySpawnType.LIVING),
HORSE(NamespaceID.from("minecraft:horse"), 1.3964844, 1.6, HorseMeta::new, EntitySpawnType.LIVING),
HUSK("minecraft:husk", 0.6, 1.95, HuskMeta::new, EntitySpawnType.LIVING),
HUSK(NamespaceID.from("minecraft:husk"), 0.6, 1.95, HuskMeta::new, EntitySpawnType.LIVING),
ILLUSIONER("minecraft:illusioner", 0.6, 1.95, IllusionerMeta::new, EntitySpawnType.LIVING),
ILLUSIONER(NamespaceID.from("minecraft:illusioner"), 0.6, 1.95, IllusionerMeta::new, EntitySpawnType.LIVING),
IRON_GOLEM("minecraft:iron_golem", 1.4, 2.7, IronGolemMeta::new, EntitySpawnType.LIVING),
IRON_GOLEM(NamespaceID.from("minecraft:iron_golem"), 1.4, 2.7, IronGolemMeta::new, EntitySpawnType.LIVING),
ITEM("minecraft:item", 0.25, 0.25, ItemEntityMeta::new, EntitySpawnType.BASE),
ITEM(NamespaceID.from("minecraft:item"), 0.25, 0.25, ItemEntityMeta::new, EntitySpawnType.BASE),
ITEM_FRAME("minecraft:item_frame", 0.5, 0.5, ItemFrameMeta::new, EntitySpawnType.BASE),
ITEM_FRAME(NamespaceID.from("minecraft:item_frame"), 0.5, 0.5, ItemFrameMeta::new, EntitySpawnType.BASE),
FIREBALL("minecraft:fireball", 1.0, 1.0, FireballMeta::new, EntitySpawnType.BASE),
FIREBALL(NamespaceID.from("minecraft:fireball"), 1.0, 1.0, FireballMeta::new, EntitySpawnType.BASE),
LEASH_KNOT("minecraft:leash_knot", 0.5, 0.5, LeashKnotMeta::new, EntitySpawnType.BASE),
LEASH_KNOT(NamespaceID.from("minecraft:leash_knot"), 0.5, 0.5, LeashKnotMeta::new, EntitySpawnType.BASE),
LIGHTNING_BOLT("minecraft:lightning_bolt", 0.0, 0.0, LightningBoltMeta::new, EntitySpawnType.BASE),
LIGHTNING_BOLT(NamespaceID.from("minecraft:lightning_bolt"), 0.0, 0.0, LightningBoltMeta::new, EntitySpawnType.BASE),
LLAMA("minecraft:llama", 0.9, 1.87, LlamaMeta::new, EntitySpawnType.LIVING),
LLAMA(NamespaceID.from("minecraft:llama"), 0.9, 1.87, LlamaMeta::new, EntitySpawnType.LIVING),
LLAMA_SPIT("minecraft:llama_spit", 0.25, 0.25, LlamaSpitMeta::new, EntitySpawnType.BASE),
LLAMA_SPIT(NamespaceID.from("minecraft:llama_spit"), 0.25, 0.25, LlamaSpitMeta::new, EntitySpawnType.BASE),
MAGMA_CUBE("minecraft:magma_cube", 2.04, 2.04, MagmaCubeMeta::new, EntitySpawnType.LIVING),
MAGMA_CUBE(NamespaceID.from("minecraft:magma_cube"), 2.04, 2.04, MagmaCubeMeta::new, EntitySpawnType.LIVING),
MINECART("minecraft:minecart", 0.98, 0.7, MinecartMeta::new, EntitySpawnType.BASE),
MINECART(NamespaceID.from("minecraft:minecart"), 0.98, 0.7, MinecartMeta::new, EntitySpawnType.BASE),
CHEST_MINECART("minecraft:chest_minecart", 0.98, 0.7, ChestMinecartMeta::new, EntitySpawnType.BASE),
CHEST_MINECART(NamespaceID.from("minecraft:chest_minecart"), 0.98, 0.7, ChestMinecartMeta::new, EntitySpawnType.BASE),
COMMAND_BLOCK_MINECART("minecraft:command_block_minecart", 0.98, 0.7, CommandBlockMinecartMeta::new, EntitySpawnType.BASE),
COMMAND_BLOCK_MINECART(NamespaceID.from("minecraft:command_block_minecart"), 0.98, 0.7, CommandBlockMinecartMeta::new, EntitySpawnType.BASE),
FURNACE_MINECART("minecraft:furnace_minecart", 0.98, 0.7, FurnaceMinecartMeta::new, EntitySpawnType.BASE),
FURNACE_MINECART(NamespaceID.from("minecraft:furnace_minecart"), 0.98, 0.7, FurnaceMinecartMeta::new, EntitySpawnType.BASE),
HOPPER_MINECART("minecraft:hopper_minecart", 0.98, 0.7, HopperMinecartMeta::new, EntitySpawnType.BASE),
HOPPER_MINECART(NamespaceID.from("minecraft:hopper_minecart"), 0.98, 0.7, HopperMinecartMeta::new, EntitySpawnType.BASE),
SPAWNER_MINECART("minecraft:spawner_minecart", 0.98, 0.7, SpawnerMinecartMeta::new, EntitySpawnType.BASE),
SPAWNER_MINECART(NamespaceID.from("minecraft:spawner_minecart"), 0.98, 0.7, SpawnerMinecartMeta::new, EntitySpawnType.BASE),
TNT_MINECART("minecraft:tnt_minecart", 0.98, 0.7, TntMinecartMeta::new, EntitySpawnType.BASE),
TNT_MINECART(NamespaceID.from("minecraft:tnt_minecart"), 0.98, 0.7, TntMinecartMeta::new, EntitySpawnType.BASE),
MULE("minecraft:mule", 1.39648, 1.6, MuleMeta::new, EntitySpawnType.LIVING),
MULE(NamespaceID.from("minecraft:mule"), 1.3964844, 1.6, MuleMeta::new, EntitySpawnType.LIVING),
MOOSHROOM("minecraft:mooshroom", 0.9, 1.4, MooshroomMeta::new, EntitySpawnType.LIVING),
MOOSHROOM(NamespaceID.from("minecraft:mooshroom"), 0.9, 1.4, MooshroomMeta::new, EntitySpawnType.LIVING),
OCELOT("minecraft:ocelot", 0.6, 0.7, OcelotMeta::new, EntitySpawnType.LIVING),
OCELOT(NamespaceID.from("minecraft:ocelot"), 0.6, 0.7, OcelotMeta::new, EntitySpawnType.LIVING),
PAINTING("minecraft:painting", 0.5, 0.5, PaintingMeta::new, EntitySpawnType.PAINTING),
PAINTING(NamespaceID.from("minecraft:painting"), 0.5, 0.5, PaintingMeta::new, EntitySpawnType.PAINTING),
PANDA("minecraft:panda", 1.3, 1.25, PandaMeta::new, EntitySpawnType.LIVING),
PANDA(NamespaceID.from("minecraft:panda"), 1.3, 1.25, PandaMeta::new, EntitySpawnType.LIVING),
PARROT("minecraft:parrot", 0.5, 0.9, ParrotMeta::new, EntitySpawnType.LIVING),
PARROT(NamespaceID.from("minecraft:parrot"), 0.5, 0.9, ParrotMeta::new, EntitySpawnType.LIVING),
PHANTOM("minecraft:phantom", 0.9, 0.5, PhantomMeta::new, EntitySpawnType.LIVING),
PHANTOM(NamespaceID.from("minecraft:phantom"), 0.9, 0.5, PhantomMeta::new, EntitySpawnType.LIVING),
PIG("minecraft:pig", 0.9, 0.9, PigMeta::new, EntitySpawnType.LIVING),
PIG(NamespaceID.from("minecraft:pig"), 0.9, 0.9, PigMeta::new, EntitySpawnType.LIVING),
PIGLIN("minecraft:piglin", 0.6, 1.95, PiglinMeta::new, EntitySpawnType.LIVING),
PIGLIN(NamespaceID.from("minecraft:piglin"), 0.6, 1.95, PiglinMeta::new, EntitySpawnType.LIVING),
PIGLIN_BRUTE("minecraft:piglin_brute", 0.6, 1.95, PiglinBruteMeta::new, EntitySpawnType.LIVING),
PIGLIN_BRUTE(NamespaceID.from("minecraft:piglin_brute"), 0.6, 1.95, PiglinBruteMeta::new, EntitySpawnType.LIVING),
PILLAGER("minecraft:pillager", 0.6, 1.95, PillagerMeta::new, EntitySpawnType.LIVING),
PILLAGER(NamespaceID.from("minecraft:pillager"), 0.6, 1.95, PillagerMeta::new, EntitySpawnType.LIVING),
POLAR_BEAR("minecraft:polar_bear", 1.4, 1.4, PolarBearMeta::new, EntitySpawnType.LIVING),
POLAR_BEAR(NamespaceID.from("minecraft:polar_bear"), 1.4, 1.4, PolarBearMeta::new, EntitySpawnType.LIVING),
TNT("minecraft:tnt", 0.98, 0.98, PrimedTntMeta::new, EntitySpawnType.BASE),
TNT(NamespaceID.from("minecraft:tnt"), 0.98, 0.98, PrimedTntMeta::new, EntitySpawnType.BASE),
PUFFERFISH("minecraft:pufferfish", 0.7, 0.7, PufferfishMeta::new, EntitySpawnType.LIVING),
PUFFERFISH(NamespaceID.from("minecraft:pufferfish"), 0.7, 0.7, PufferfishMeta::new, EntitySpawnType.LIVING),
RABBIT("minecraft:rabbit", 0.4, 0.5, RabbitMeta::new, EntitySpawnType.LIVING),
RABBIT(NamespaceID.from("minecraft:rabbit"), 0.4, 0.5, RabbitMeta::new, EntitySpawnType.LIVING),
RAVAGER("minecraft:ravager", 1.95, 2.2, RavagerMeta::new, EntitySpawnType.LIVING),
RAVAGER(NamespaceID.from("minecraft:ravager"), 1.95, 2.2, RavagerMeta::new, EntitySpawnType.LIVING),
SALMON("minecraft:salmon", 0.7, 0.4, SalmonMeta::new, EntitySpawnType.LIVING),
SALMON(NamespaceID.from("minecraft:salmon"), 0.7, 0.4, SalmonMeta::new, EntitySpawnType.LIVING),
SHEEP("minecraft:sheep", 0.9, 1.3, SheepMeta::new, EntitySpawnType.LIVING),
SHEEP(NamespaceID.from("minecraft:sheep"), 0.9, 1.3, SheepMeta::new, EntitySpawnType.LIVING),
SHULKER("minecraft:shulker", 1.0, 1.0, ShulkerMeta::new, EntitySpawnType.LIVING),
SHULKER(NamespaceID.from("minecraft:shulker"), 1.0, 1.0, ShulkerMeta::new, EntitySpawnType.LIVING),
SHULKER_BULLET("minecraft:shulker_bullet", 0.3125, 0.3125, ShulkerBulletMeta::new, EntitySpawnType.BASE),
SHULKER_BULLET(NamespaceID.from("minecraft:shulker_bullet"), 0.3125, 0.3125, ShulkerBulletMeta::new, EntitySpawnType.BASE),
SILVERFISH("minecraft:silverfish", 0.4, 0.3, SilverfishMeta::new, EntitySpawnType.LIVING),
SILVERFISH(NamespaceID.from("minecraft:silverfish"), 0.4, 0.3, SilverfishMeta::new, EntitySpawnType.LIVING),
SKELETON("minecraft:skeleton", 0.6, 1.99, SkeletonMeta::new, EntitySpawnType.LIVING),
SKELETON(NamespaceID.from("minecraft:skeleton"), 0.6, 1.99, SkeletonMeta::new, EntitySpawnType.LIVING),
SKELETON_HORSE("minecraft:skeleton_horse", 1.39648, 1.6, SkeletonHorseMeta::new, EntitySpawnType.LIVING),
SKELETON_HORSE(NamespaceID.from("minecraft:skeleton_horse"), 1.3964844, 1.6, SkeletonHorseMeta::new, EntitySpawnType.LIVING),
SLIME("minecraft:slime", 2.04, 2.04, SlimeMeta::new, EntitySpawnType.LIVING),
SLIME(NamespaceID.from("minecraft:slime"), 2.04, 2.04, SlimeMeta::new, EntitySpawnType.LIVING),
SMALL_FIREBALL("minecraft:small_fireball", 0.3125, 0.3125, SmallFireballMeta::new, EntitySpawnType.BASE),
SMALL_FIREBALL(NamespaceID.from("minecraft:small_fireball"), 0.3125, 0.3125, SmallFireballMeta::new, EntitySpawnType.BASE),
SNOW_GOLEM("minecraft:snow_golem", 0.7, 1.9, SnowGolemMeta::new, EntitySpawnType.LIVING),
SNOW_GOLEM(NamespaceID.from("minecraft:snow_golem"), 0.7, 1.9, SnowGolemMeta::new, EntitySpawnType.LIVING),
SNOWBALL("minecraft:snowball", 0.25, 0.25, SnowballMeta::new, EntitySpawnType.BASE),
SNOWBALL(NamespaceID.from("minecraft:snowball"), 0.25, 0.25, SnowballMeta::new, EntitySpawnType.BASE),
SPECTRAL_ARROW("minecraft:spectral_arrow", 0.5, 0.5, SpectralArrowMeta::new, EntitySpawnType.BASE),
SPECTRAL_ARROW(NamespaceID.from("minecraft:spectral_arrow"), 0.5, 0.5, SpectralArrowMeta::new, EntitySpawnType.BASE),
SPIDER("minecraft:spider", 1.4, 0.9, SpiderMeta::new, EntitySpawnType.LIVING),
SPIDER(NamespaceID.from("minecraft:spider"), 1.4, 0.9, SpiderMeta::new, EntitySpawnType.LIVING),
SQUID("minecraft:squid", 0.8, 0.8, SquidMeta::new, EntitySpawnType.LIVING),
SQUID(NamespaceID.from("minecraft:squid"), 0.8, 0.8, SquidMeta::new, EntitySpawnType.LIVING),
STRAY("minecraft:stray", 0.6, 1.99, StrayMeta::new, EntitySpawnType.LIVING),
STRAY(NamespaceID.from("minecraft:stray"), 0.6, 1.99, StrayMeta::new, EntitySpawnType.LIVING),
STRIDER("minecraft:strider", 0.9, 1.7, StriderMeta::new, EntitySpawnType.LIVING),
STRIDER(NamespaceID.from("minecraft:strider"), 0.9, 1.7, StriderMeta::new, EntitySpawnType.LIVING),
EGG("minecraft:egg", 0.25, 0.25, ThrownEggMeta::new, EntitySpawnType.BASE),
EGG(NamespaceID.from("minecraft:egg"), 0.25, 0.25, ThrownEggMeta::new, EntitySpawnType.BASE),
ENDER_PEARL("minecraft:ender_pearl", 0.25, 0.25, ThrownEnderPearlMeta::new, EntitySpawnType.BASE),
ENDER_PEARL(NamespaceID.from("minecraft:ender_pearl"), 0.25, 0.25, ThrownEnderPearlMeta::new, EntitySpawnType.BASE),
EXPERIENCE_BOTTLE("minecraft:experience_bottle", 0.25, 0.25, ThrownExperienceBottleMeta::new, EntitySpawnType.BASE),
EXPERIENCE_BOTTLE(NamespaceID.from("minecraft:experience_bottle"), 0.25, 0.25, ThrownExperienceBottleMeta::new, EntitySpawnType.BASE),
POTION("minecraft:potion", 0.25, 0.25, ThrownPotionMeta::new, EntitySpawnType.BASE),
POTION(NamespaceID.from("minecraft:potion"), 0.25, 0.25, ThrownPotionMeta::new, EntitySpawnType.BASE),
TRIDENT("minecraft:trident", 0.5, 0.5, ThrownTridentMeta::new, EntitySpawnType.BASE),
TRIDENT(NamespaceID.from("minecraft:trident"), 0.5, 0.5, ThrownTridentMeta::new, EntitySpawnType.BASE),
TRADER_LLAMA("minecraft:trader_llama", 0.9, 1.87, TraderLlamaMeta::new, EntitySpawnType.BASE),
TRADER_LLAMA(NamespaceID.from("minecraft:trader_llama"), 0.9, 1.87, TraderLlamaMeta::new, EntitySpawnType.LIVING),
TROPICAL_FISH("minecraft:tropical_fish", 0.5, 0.4, TropicalFishMeta::new, EntitySpawnType.LIVING),
TROPICAL_FISH(NamespaceID.from("minecraft:tropical_fish"), 0.5, 0.4, TropicalFishMeta::new, EntitySpawnType.LIVING),
TURTLE("minecraft:turtle", 1.2, 0.4, TurtleMeta::new, EntitySpawnType.LIVING),
TURTLE(NamespaceID.from("minecraft:turtle"), 1.2, 0.4, TurtleMeta::new, EntitySpawnType.LIVING),
VEX("minecraft:vex", 0.4, 0.8, VexMeta::new, EntitySpawnType.LIVING),
VEX(NamespaceID.from("minecraft:vex"), 0.4, 0.8, VexMeta::new, EntitySpawnType.LIVING),
VILLAGER("minecraft:villager", 0.6, 1.95, VillagerMeta::new, EntitySpawnType.LIVING),
VILLAGER(NamespaceID.from("minecraft:villager"), 0.6, 1.95, VillagerMeta::new, EntitySpawnType.LIVING),
VINDICATOR("minecraft:vindicator", 0.6, 1.95, VindicatorMeta::new, EntitySpawnType.LIVING),
VINDICATOR(NamespaceID.from("minecraft:vindicator"), 0.6, 1.95, VindicatorMeta::new, EntitySpawnType.LIVING),
WANDERING_TRADER("minecraft:wandering_trader", 0.6, 1.95, WanderingTraderMeta::new, EntitySpawnType.LIVING),
WANDERING_TRADER(NamespaceID.from("minecraft:wandering_trader"), 0.6, 1.95, WanderingTraderMeta::new, EntitySpawnType.LIVING),
WITCH("minecraft:witch", 0.6, 1.95, WitchMeta::new, EntitySpawnType.LIVING),
WITCH(NamespaceID.from("minecraft:witch"), 0.6, 1.95, WitchMeta::new, EntitySpawnType.LIVING),
WITHER("minecraft:wither", 0.9, 3.5, WitherMeta::new, EntitySpawnType.LIVING),
WITHER(NamespaceID.from("minecraft:wither"), 0.9, 3.5, WitherMeta::new, EntitySpawnType.LIVING),
WITHER_SKELETON("minecraft:wither_skeleton", 0.7, 2.4, WitherSkeletonMeta::new, EntitySpawnType.LIVING),
WITHER_SKELETON(NamespaceID.from("minecraft:wither_skeleton"), 0.7, 2.4, WitherSkeletonMeta::new, EntitySpawnType.LIVING),
WITHER_SKULL("minecraft:wither_skull", 0.3125, 0.3125, WitherSkullMeta::new, EntitySpawnType.BASE),
WITHER_SKULL(NamespaceID.from("minecraft:wither_skull"), 0.3125, 0.3125, WitherSkullMeta::new, EntitySpawnType.BASE),
WOLF("minecraft:wolf", 0.6, 0.85, WolfMeta::new, EntitySpawnType.LIVING),
WOLF(NamespaceID.from("minecraft:wolf"), 0.6, 0.85, WolfMeta::new, EntitySpawnType.LIVING),
ZOGLIN("minecraft:zoglin", 1.39648, 1.4, ZoglinMeta::new, EntitySpawnType.LIVING),
ZOGLIN(NamespaceID.from("minecraft:zoglin"), 1.3964844, 1.4, ZoglinMeta::new, EntitySpawnType.LIVING),
ZOMBIE("minecraft:zombie", 0.6, 1.95, ZombieMeta::new, EntitySpawnType.LIVING),
ZOMBIE(NamespaceID.from("minecraft:zombie"), 0.6, 1.95, ZombieMeta::new, EntitySpawnType.LIVING),
ZOMBIE_HORSE("minecraft:zombie_horse", 1.39648, 1.6, ZombieHorseMeta::new, EntitySpawnType.LIVING),
ZOMBIE_HORSE(NamespaceID.from("minecraft:zombie_horse"), 1.3964844, 1.6, ZombieHorseMeta::new, EntitySpawnType.LIVING),
ZOMBIE_VILLAGER("minecraft:zombie_villager", 0.6, 1.95, ZombieVillagerMeta::new, EntitySpawnType.LIVING),
ZOMBIE_VILLAGER(NamespaceID.from("minecraft:zombie_villager"), 0.6, 1.95, ZombieVillagerMeta::new, EntitySpawnType.LIVING),
ZOMBIFIED_PIGLIN("minecraft:zombified_piglin", 0.6, 1.95, ZombifiedPiglinMeta::new, EntitySpawnType.LIVING),
ZOMBIFIED_PIGLIN(NamespaceID.from("minecraft:zombified_piglin"), 0.6, 1.95, ZombifiedPiglinMeta::new, EntitySpawnType.LIVING),
PLAYER("minecraft:player", 0.6, 1.8, PlayerMeta::new, EntitySpawnType.PLAYER),
PLAYER(NamespaceID.from("minecraft:player"), 0.6, 1.8, PlayerMeta::new, EntitySpawnType.PLAYER),
FISHING_BOBBER("minecraft:fishing_bobber", 0.25, 0.25, FishingHookMeta::new, EntitySpawnType.BASE);
FISHING_BOBBER(NamespaceID.from("minecraft:fishing_bobber"), 0.25, 0.25, FishingHookMeta::new, EntitySpawnType.BASE);
private static final EntityType[] VALUES = values();
@NotNull
private final String namespaceID;
private final NamespaceID id;
private final double width;
@ -278,26 +352,30 @@ public enum EntityType implements Keyed {
@NotNull
private final EntitySpawnType spawnType;
private final Key key;
EntityType(@NotNull String namespaceID, double width, double height,
EntityType(@NotNull NamespaceID id, double width, double height,
@NotNull BiFunction<Entity, Metadata, EntityMeta> metaConstructor,
@NotNull EntitySpawnType spawnType) {
this.namespaceID = namespaceID;
this.id = id;
this.width = width;
this.height = height;
this.metaConstructor = metaConstructor;
this.spawnType = spawnType;
Registries.entityTypes.put(NamespaceID.from(namespaceID), this);
this.key = Key.key(this.namespaceID);
Registries.entityTypes.put(id, this);
}
@Override
@NotNull
public Key key() {
return this.id;
}
public short getId() {
return (short) ordinal();
}
public String getNamespaceID() {
return this.namespaceID;
@NotNull
public NamespaceID getNamespaceID() {
return this.id;
}
public double getWidth() {
@ -316,6 +394,7 @@ public enum EntityType implements Keyed {
return this.spawnType;
}
@Nullable
public static EntityType fromId(short id) {
if(id >= 0 && id < VALUES.length) {
return VALUES[id];
@ -323,7 +402,9 @@ public enum EntityType implements Keyed {
return null;
}
public Key key() {
return this.key;
@NotNull
@Override
public String toString() {
return "[" + this.id + "]";
}
}

View File

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

View File

@ -1,53 +0,0 @@
package net.minestom.server.fluids;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import net.minestom.server.registry.Registries;
import net.minestom.server.utils.NamespaceID;
/**
* //==============================
* // AUTOGENERATED BY EnumGenerator
* //==============================
*/
@SuppressWarnings({"deprecation"})
public enum Fluid implements Keyed {
EMPTY("minecraft:empty"),
FLOWING_WATER("minecraft:flowing_water"),
WATER("minecraft:water"),
FLOWING_LAVA("minecraft:flowing_lava"),
LAVA("minecraft:lava");
private final String namespaceID;
private final Key key;
Fluid(String namespaceID) {
this.namespaceID = namespaceID;
Registries.fluids.put(NamespaceID.from(namespaceID), this);
this.key = Key.key(this.namespaceID);
}
public int getId() {
return ordinal();
}
public String getNamespaceID() {
return namespaceID;
}
public Key key() {
return this.key;
}
public static Fluid fromId(int id) {
if (id >= 0 && id < values().length) {
return values()[id];
}
return EMPTY;
}
}

View File

@ -4,116 +4,125 @@ 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 EnumGenerator
* //==============================
* AUTOGENERATED by EnchantmentGenerator
*/
@SuppressWarnings({"deprecation"})
public enum Enchantment implements Keyed {
PROTECTION("minecraft:protection"),
ALL_DAMAGE_PROTECTION(NamespaceID.from("minecraft:protection")),
FIRE_PROTECTION("minecraft:fire_protection"),
FIRE_PROTECTION(NamespaceID.from("minecraft:fire_protection")),
FEATHER_FALLING("minecraft:feather_falling"),
FALL_PROTECTION(NamespaceID.from("minecraft:feather_falling")),
BLAST_PROTECTION("minecraft:blast_protection"),
BLAST_PROTECTION(NamespaceID.from("minecraft:blast_protection")),
PROJECTILE_PROTECTION("minecraft:projectile_protection"),
PROJECTILE_PROTECTION(NamespaceID.from("minecraft:projectile_protection")),
RESPIRATION("minecraft:respiration"),
RESPIRATION(NamespaceID.from("minecraft:respiration")),
AQUA_AFFINITY("minecraft:aqua_affinity"),
AQUA_AFFINITY(NamespaceID.from("minecraft:aqua_affinity")),
THORNS("minecraft:thorns"),
THORNS(NamespaceID.from("minecraft:thorns")),
DEPTH_STRIDER("minecraft:depth_strider"),
DEPTH_STRIDER(NamespaceID.from("minecraft:depth_strider")),
FROST_WALKER("minecraft:frost_walker"),
FROST_WALKER(NamespaceID.from("minecraft:frost_walker")),
BINDING_CURSE("minecraft:binding_curse"),
BINDING_CURSE(NamespaceID.from("minecraft:binding_curse")),
SOUL_SPEED("minecraft:soul_speed"),
SOUL_SPEED(NamespaceID.from("minecraft:soul_speed")),
SHARPNESS("minecraft:sharpness"),
SHARPNESS(NamespaceID.from("minecraft:sharpness")),
SMITE("minecraft:smite"),
SMITE(NamespaceID.from("minecraft:smite")),
BANE_OF_ARTHROPODS("minecraft:bane_of_arthropods"),
BANE_OF_ARTHROPODS(NamespaceID.from("minecraft:bane_of_arthropods")),
KNOCKBACK("minecraft:knockback"),
KNOCKBACK(NamespaceID.from("minecraft:knockback")),
FIRE_ASPECT("minecraft:fire_aspect"),
FIRE_ASPECT(NamespaceID.from("minecraft:fire_aspect")),
LOOTING("minecraft:looting"),
MOB_LOOTING(NamespaceID.from("minecraft:looting")),
SWEEPING("minecraft:sweeping"),
SWEEPING_EDGE(NamespaceID.from("minecraft:sweeping")),
EFFICIENCY("minecraft:efficiency"),
BLOCK_EFFICIENCY(NamespaceID.from("minecraft:efficiency")),
SILK_TOUCH("minecraft:silk_touch"),
SILK_TOUCH(NamespaceID.from("minecraft:silk_touch")),
UNBREAKING("minecraft:unbreaking"),
UNBREAKING(NamespaceID.from("minecraft:unbreaking")),
FORTUNE("minecraft:fortune"),
BLOCK_FORTUNE(NamespaceID.from("minecraft:fortune")),
POWER("minecraft:power"),
POWER_ARROWS(NamespaceID.from("minecraft:power")),
PUNCH("minecraft:punch"),
PUNCH_ARROWS(NamespaceID.from("minecraft:punch")),
FLAME("minecraft:flame"),
FLAMING_ARROWS(NamespaceID.from("minecraft:flame")),
INFINITY("minecraft:infinity"),
INFINITY_ARROWS(NamespaceID.from("minecraft:infinity")),
LUCK_OF_THE_SEA("minecraft:luck_of_the_sea"),
FISHING_LUCK(NamespaceID.from("minecraft:luck_of_the_sea")),
LURE("minecraft:lure"),
FISHING_SPEED(NamespaceID.from("minecraft:lure")),
LOYALTY("minecraft:loyalty"),
LOYALTY(NamespaceID.from("minecraft:loyalty")),
IMPALING("minecraft:impaling"),
IMPALING(NamespaceID.from("minecraft:impaling")),
RIPTIDE("minecraft:riptide"),
RIPTIDE(NamespaceID.from("minecraft:riptide")),
CHANNELING("minecraft:channeling"),
CHANNELING(NamespaceID.from("minecraft:channeling")),
MULTISHOT("minecraft:multishot"),
MULTISHOT(NamespaceID.from("minecraft:multishot")),
QUICK_CHARGE("minecraft:quick_charge"),
QUICK_CHARGE(NamespaceID.from("minecraft:quick_charge")),
PIERCING("minecraft:piercing"),
PIERCING(NamespaceID.from("minecraft:piercing")),
MENDING("minecraft:mending"),
MENDING(NamespaceID.from("minecraft:mending")),
VANISHING_CURSE("minecraft:vanishing_curse");
VANISHING_CURSE(NamespaceID.from("minecraft:vanishing_curse"));
private final String namespaceID;
private static final Enchantment[] VALUES = values();
private final Key key;
@NotNull
private final NamespaceID id;
Enchantment(String namespaceID) {
this.namespaceID = namespaceID;
Registries.enchantments.put(NamespaceID.from(namespaceID), this);
this.key = Key.key(this.namespaceID);
}
public int getId() {
return ordinal();
}
public String getNamespaceID() {
return namespaceID;
Enchantment(@NotNull NamespaceID id) {
this.id = id;
Registries.enchantments.put(id, this);
}
@Override
@NotNull
public Key key() {
return this.key;
return this.id;
}
public static Enchantment fromId(int id) {
if (id >= 0 && id < values().length) {
return values()[id];
public short getId() {
return (short) ordinal();
}
@NotNull
public NamespaceID getNamespaceID() {
return this.id;
}
@Nullable
public static Enchantment fromId(short id) {
if(id >= 0 && id < VALUES.length) {
return VALUES[id];
}
return null;
}
@NotNull
@Override
public String toString() {
return "[" + this.id + "]";
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,184 +4,193 @@ 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 EnumGenerator
* //==============================
* AUTOGENERATED by ParticleGenerator
*/
@SuppressWarnings({"deprecation"})
public enum Particle implements Keyed {
AMBIENT_ENTITY_EFFECT("minecraft:ambient_entity_effect"),
AMBIENT_ENTITY_EFFECT(NamespaceID.from("minecraft:ambient_entity_effect")),
ANGRY_VILLAGER("minecraft:angry_villager"),
ANGRY_VILLAGER(NamespaceID.from("minecraft:angry_villager")),
BARRIER("minecraft:barrier"),
BARRIER(NamespaceID.from("minecraft:barrier")),
BLOCK("minecraft:block"),
BLOCK(NamespaceID.from("minecraft:block")),
BUBBLE("minecraft:bubble"),
BUBBLE(NamespaceID.from("minecraft:bubble")),
CLOUD("minecraft:cloud"),
CLOUD(NamespaceID.from("minecraft:cloud")),
CRIT("minecraft:crit"),
CRIT(NamespaceID.from("minecraft:crit")),
DAMAGE_INDICATOR("minecraft:damage_indicator"),
DAMAGE_INDICATOR(NamespaceID.from("minecraft:damage_indicator")),
DRAGON_BREATH("minecraft:dragon_breath"),
DRAGON_BREATH(NamespaceID.from("minecraft:dragon_breath")),
DRIPPING_LAVA("minecraft:dripping_lava"),
DRIPPING_LAVA(NamespaceID.from("minecraft:dripping_lava")),
FALLING_LAVA("minecraft:falling_lava"),
FALLING_LAVA(NamespaceID.from("minecraft:falling_lava")),
LANDING_LAVA("minecraft:landing_lava"),
LANDING_LAVA(NamespaceID.from("minecraft:landing_lava")),
DRIPPING_WATER("minecraft:dripping_water"),
DRIPPING_WATER(NamespaceID.from("minecraft:dripping_water")),
FALLING_WATER("minecraft:falling_water"),
FALLING_WATER(NamespaceID.from("minecraft:falling_water")),
DUST("minecraft:dust"),
DUST(NamespaceID.from("minecraft:dust")),
EFFECT("minecraft:effect"),
EFFECT(NamespaceID.from("minecraft:effect")),
ELDER_GUARDIAN("minecraft:elder_guardian"),
ELDER_GUARDIAN(NamespaceID.from("minecraft:elder_guardian")),
ENCHANTED_HIT("minecraft:enchanted_hit"),
ENCHANTED_HIT(NamespaceID.from("minecraft:enchanted_hit")),
ENCHANT("minecraft:enchant"),
ENCHANT(NamespaceID.from("minecraft:enchant")),
END_ROD("minecraft:end_rod"),
END_ROD(NamespaceID.from("minecraft:end_rod")),
ENTITY_EFFECT("minecraft:entity_effect"),
ENTITY_EFFECT(NamespaceID.from("minecraft:entity_effect")),
EXPLOSION_EMITTER("minecraft:explosion_emitter"),
EXPLOSION_EMITTER(NamespaceID.from("minecraft:explosion_emitter")),
EXPLOSION("minecraft:explosion"),
EXPLOSION(NamespaceID.from("minecraft:explosion")),
FALLING_DUST("minecraft:falling_dust"),
FALLING_DUST(NamespaceID.from("minecraft:falling_dust")),
FIREWORK("minecraft:firework"),
FIREWORK(NamespaceID.from("minecraft:firework")),
FISHING("minecraft:fishing"),
FISHING(NamespaceID.from("minecraft:fishing")),
FLAME("minecraft:flame"),
FLAME(NamespaceID.from("minecraft:flame")),
SOUL_FIRE_FLAME("minecraft:soul_fire_flame"),
SOUL_FIRE_FLAME(NamespaceID.from("minecraft:soul_fire_flame")),
SOUL("minecraft:soul"),
SOUL(NamespaceID.from("minecraft:soul")),
FLASH("minecraft:flash"),
FLASH(NamespaceID.from("minecraft:flash")),
HAPPY_VILLAGER("minecraft:happy_villager"),
HAPPY_VILLAGER(NamespaceID.from("minecraft:happy_villager")),
COMPOSTER("minecraft:composter"),
COMPOSTER(NamespaceID.from("minecraft:composter")),
HEART("minecraft:heart"),
HEART(NamespaceID.from("minecraft:heart")),
INSTANT_EFFECT("minecraft:instant_effect"),
INSTANT_EFFECT(NamespaceID.from("minecraft:instant_effect")),
ITEM("minecraft:item"),
ITEM(NamespaceID.from("minecraft:item")),
ITEM_SLIME("minecraft:item_slime"),
ITEM_SLIME(NamespaceID.from("minecraft:item_slime")),
ITEM_SNOWBALL("minecraft:item_snowball"),
ITEM_SNOWBALL(NamespaceID.from("minecraft:item_snowball")),
LARGE_SMOKE("minecraft:large_smoke"),
LARGE_SMOKE(NamespaceID.from("minecraft:large_smoke")),
LAVA("minecraft:lava"),
LAVA(NamespaceID.from("minecraft:lava")),
MYCELIUM("minecraft:mycelium"),
MYCELIUM(NamespaceID.from("minecraft:mycelium")),
NOTE("minecraft:note"),
NOTE(NamespaceID.from("minecraft:note")),
POOF("minecraft:poof"),
POOF(NamespaceID.from("minecraft:poof")),
PORTAL("minecraft:portal"),
PORTAL(NamespaceID.from("minecraft:portal")),
RAIN("minecraft:rain"),
RAIN(NamespaceID.from("minecraft:rain")),
SMOKE("minecraft:smoke"),
SMOKE(NamespaceID.from("minecraft:smoke")),
SNEEZE("minecraft:sneeze"),
SNEEZE(NamespaceID.from("minecraft:sneeze")),
SPIT("minecraft:spit"),
SPIT(NamespaceID.from("minecraft:spit")),
SQUID_INK("minecraft:squid_ink"),
SQUID_INK(NamespaceID.from("minecraft:squid_ink")),
SWEEP_ATTACK("minecraft:sweep_attack"),
SWEEP_ATTACK(NamespaceID.from("minecraft:sweep_attack")),
TOTEM_OF_UNDYING("minecraft:totem_of_undying"),
TOTEM_OF_UNDYING(NamespaceID.from("minecraft:totem_of_undying")),
UNDERWATER("minecraft:underwater"),
UNDERWATER(NamespaceID.from("minecraft:underwater")),
SPLASH("minecraft:splash"),
SPLASH(NamespaceID.from("minecraft:splash")),
WITCH("minecraft:witch"),
WITCH(NamespaceID.from("minecraft:witch")),
BUBBLE_POP("minecraft:bubble_pop"),
BUBBLE_POP(NamespaceID.from("minecraft:bubble_pop")),
CURRENT_DOWN("minecraft:current_down"),
CURRENT_DOWN(NamespaceID.from("minecraft:current_down")),
BUBBLE_COLUMN_UP("minecraft:bubble_column_up"),
BUBBLE_COLUMN_UP(NamespaceID.from("minecraft:bubble_column_up")),
NAUTILUS("minecraft:nautilus"),
NAUTILUS(NamespaceID.from("minecraft:nautilus")),
DOLPHIN("minecraft:dolphin"),
DOLPHIN(NamespaceID.from("minecraft:dolphin")),
CAMPFIRE_COSY_SMOKE("minecraft:campfire_cosy_smoke"),
CAMPFIRE_COSY_SMOKE(NamespaceID.from("minecraft:campfire_cosy_smoke")),
CAMPFIRE_SIGNAL_SMOKE("minecraft:campfire_signal_smoke"),
CAMPFIRE_SIGNAL_SMOKE(NamespaceID.from("minecraft:campfire_signal_smoke")),
DRIPPING_HONEY("minecraft:dripping_honey"),
DRIPPING_HONEY(NamespaceID.from("minecraft:dripping_honey")),
FALLING_HONEY("minecraft:falling_honey"),
FALLING_HONEY(NamespaceID.from("minecraft:falling_honey")),
LANDING_HONEY("minecraft:landing_honey"),
LANDING_HONEY(NamespaceID.from("minecraft:landing_honey")),
FALLING_NECTAR("minecraft:falling_nectar"),
FALLING_NECTAR(NamespaceID.from("minecraft:falling_nectar")),
ASH("minecraft:ash"),
ASH(NamespaceID.from("minecraft:ash")),
CRIMSON_SPORE("minecraft:crimson_spore"),
CRIMSON_SPORE(NamespaceID.from("minecraft:crimson_spore")),
WARPED_SPORE("minecraft:warped_spore"),
WARPED_SPORE(NamespaceID.from("minecraft:warped_spore")),
DRIPPING_OBSIDIAN_TEAR("minecraft:dripping_obsidian_tear"),
DRIPPING_OBSIDIAN_TEAR(NamespaceID.from("minecraft:dripping_obsidian_tear")),
FALLING_OBSIDIAN_TEAR("minecraft:falling_obsidian_tear"),
FALLING_OBSIDIAN_TEAR(NamespaceID.from("minecraft:falling_obsidian_tear")),
LANDING_OBSIDIAN_TEAR("minecraft:landing_obsidian_tear"),
LANDING_OBSIDIAN_TEAR(NamespaceID.from("minecraft:landing_obsidian_tear")),
REVERSE_PORTAL("minecraft:reverse_portal"),
REVERSE_PORTAL(NamespaceID.from("minecraft:reverse_portal")),
WHITE_ASH("minecraft:white_ash");
WHITE_ASH(NamespaceID.from("minecraft:white_ash"));
private final String namespaceID;
private static final Particle[] VALUES = values();
private final Key key;
@NotNull
private final NamespaceID id;
Particle(String namespaceID) {
this.namespaceID = namespaceID;
Registries.particles.put(NamespaceID.from(namespaceID), this);
this.key = Key.key(this.namespaceID);
}
public int getId() {
return ordinal();
}
public String getNamespaceID() {
return namespaceID;
Particle(@NotNull NamespaceID id) {
this.id = id;
Registries.particles.put(id, this);
}
@Override
@NotNull
public Key key() {
return this.key;
return this.id;
}
public static Particle fromId(int id) {
if (id >= 0 && id < values().length) {
return values()[id];
public short getId() {
return (short) ordinal();
}
@NotNull
public NamespaceID getNamespaceID() {
return this.id;
}
@Nullable
public static Particle fromId(short id) {
if(id >= 0 && id < VALUES.length) {
return VALUES[id];
}
return null;
}
@NotNull
@Override
public String toString() {
return "[" + this.id + "]";
}
}

View File

@ -4,104 +4,113 @@ 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 EnumGenerator
* //==============================
* AUTOGENERATED by PotionEffectGenerator
*/
@SuppressWarnings({"deprecation"})
public enum PotionEffect implements Keyed {
SPEED("minecraft:speed"),
MOVEMENT_SPEED(NamespaceID.from("minecraft:speed")),
SLOWNESS("minecraft:slowness"),
MOVEMENT_SLOWDOWN(NamespaceID.from("minecraft:slowness")),
HASTE("minecraft:haste"),
DIG_SPEED(NamespaceID.from("minecraft:haste")),
MINING_FATIGUE("minecraft:mining_fatigue"),
DIG_SLOWDOWN(NamespaceID.from("minecraft:mining_fatigue")),
STRENGTH("minecraft:strength"),
DAMAGE_BOOST(NamespaceID.from("minecraft:strength")),
INSTANT_HEALTH("minecraft:instant_health"),
HEAL(NamespaceID.from("minecraft:instant_health")),
INSTANT_DAMAGE("minecraft:instant_damage"),
HARM(NamespaceID.from("minecraft:instant_damage")),
JUMP_BOOST("minecraft:jump_boost"),
JUMP(NamespaceID.from("minecraft:jump_boost")),
NAUSEA("minecraft:nausea"),
CONFUSION(NamespaceID.from("minecraft:nausea")),
REGENERATION("minecraft:regeneration"),
REGENERATION(NamespaceID.from("minecraft:regeneration")),
RESISTANCE("minecraft:resistance"),
DAMAGE_RESISTANCE(NamespaceID.from("minecraft:resistance")),
FIRE_RESISTANCE("minecraft:fire_resistance"),
FIRE_RESISTANCE(NamespaceID.from("minecraft:fire_resistance")),
WATER_BREATHING("minecraft:water_breathing"),
WATER_BREATHING(NamespaceID.from("minecraft:water_breathing")),
INVISIBILITY("minecraft:invisibility"),
INVISIBILITY(NamespaceID.from("minecraft:invisibility")),
BLINDNESS("minecraft:blindness"),
BLINDNESS(NamespaceID.from("minecraft:blindness")),
NIGHT_VISION("minecraft:night_vision"),
NIGHT_VISION(NamespaceID.from("minecraft:night_vision")),
HUNGER("minecraft:hunger"),
HUNGER(NamespaceID.from("minecraft:hunger")),
WEAKNESS("minecraft:weakness"),
WEAKNESS(NamespaceID.from("minecraft:weakness")),
POISON("minecraft:poison"),
POISON(NamespaceID.from("minecraft:poison")),
WITHER("minecraft:wither"),
WITHER(NamespaceID.from("minecraft:wither")),
HEALTH_BOOST("minecraft:health_boost"),
HEALTH_BOOST(NamespaceID.from("minecraft:health_boost")),
ABSORPTION("minecraft:absorption"),
ABSORPTION(NamespaceID.from("minecraft:absorption")),
SATURATION("minecraft:saturation"),
SATURATION(NamespaceID.from("minecraft:saturation")),
GLOWING("minecraft:glowing"),
GLOWING(NamespaceID.from("minecraft:glowing")),
LEVITATION("minecraft:levitation"),
LEVITATION(NamespaceID.from("minecraft:levitation")),
LUCK("minecraft:luck"),
LUCK(NamespaceID.from("minecraft:luck")),
UNLUCK("minecraft:unluck"),
UNLUCK(NamespaceID.from("minecraft:unluck")),
SLOW_FALLING("minecraft:slow_falling"),
SLOW_FALLING(NamespaceID.from("minecraft:slow_falling")),
CONDUIT_POWER("minecraft:conduit_power"),
CONDUIT_POWER(NamespaceID.from("minecraft:conduit_power")),
DOLPHINS_GRACE("minecraft:dolphins_grace"),
DOLPHINS_GRACE(NamespaceID.from("minecraft:dolphins_grace")),
BAD_OMEN("minecraft:bad_omen"),
BAD_OMEN(NamespaceID.from("minecraft:bad_omen")),
HERO_OF_THE_VILLAGE("minecraft:hero_of_the_village");
HERO_OF_THE_VILLAGE(NamespaceID.from("minecraft:hero_of_the_village"));
private final String namespaceID;
private static final PotionEffect[] VALUES = values();
private final Key key;
@NotNull
private final NamespaceID id;
PotionEffect(String namespaceID) {
this.namespaceID = namespaceID;
Registries.potionEffects.put(NamespaceID.from(namespaceID), this);
this.key = Key.key(this.namespaceID);
}
public int getId() {
return ordinal() + 1;
}
public String getNamespaceID() {
return namespaceID;
PotionEffect(@NotNull NamespaceID id) {
this.id = id;
Registries.potionEffects.put(id, this);
}
@Override
@NotNull
public Key key() {
return this.key;
return this.id;
}
public static PotionEffect fromId(int id) {
if (id >= 0 && id < values().length + 1) {
return values()[id - 1];
public short getId() {
return (short) ordinal();
}
@NotNull
public NamespaceID getNamespaceID() {
return this.id;
}
@Nullable
public static PotionEffect fromId(short id) {
if(id >= 0 && id < VALUES.length) {
return VALUES[id];
}
return null;
}
@NotNull
@Override
public String toString() {
return "[" + this.id + "]";
}
}

View File

@ -4,126 +4,135 @@ 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 EnumGenerator
* //==============================
* AUTOGENERATED by PotionTypeGenerator
*/
@SuppressWarnings({"deprecation"})
public enum PotionType implements Keyed {
EMPTY("minecraft:empty"),
EMPTY(NamespaceID.from("minecraft:empty")),
WATER("minecraft:water"),
WATER(NamespaceID.from("minecraft:water")),
MUNDANE("minecraft:mundane"),
MUNDANE(NamespaceID.from("minecraft:mundane")),
THICK("minecraft:thick"),
THICK(NamespaceID.from("minecraft:thick")),
AWKWARD("minecraft:awkward"),
AWKWARD(NamespaceID.from("minecraft:awkward")),
NIGHT_VISION("minecraft:night_vision"),
NIGHT_VISION(NamespaceID.from("minecraft:night_vision")),
LONG_NIGHT_VISION("minecraft:long_night_vision"),
LONG_NIGHT_VISION(NamespaceID.from("minecraft:long_night_vision")),
INVISIBILITY("minecraft:invisibility"),
INVISIBILITY(NamespaceID.from("minecraft:invisibility")),
LONG_INVISIBILITY("minecraft:long_invisibility"),
LONG_INVISIBILITY(NamespaceID.from("minecraft:long_invisibility")),
LEAPING("minecraft:leaping"),
LEAPING(NamespaceID.from("minecraft:leaping")),
LONG_LEAPING("minecraft:long_leaping"),
LONG_LEAPING(NamespaceID.from("minecraft:long_leaping")),
STRONG_LEAPING("minecraft:strong_leaping"),
STRONG_LEAPING(NamespaceID.from("minecraft:strong_leaping")),
FIRE_RESISTANCE("minecraft:fire_resistance"),
FIRE_RESISTANCE(NamespaceID.from("minecraft:fire_resistance")),
LONG_FIRE_RESISTANCE("minecraft:long_fire_resistance"),
LONG_FIRE_RESISTANCE(NamespaceID.from("minecraft:long_fire_resistance")),
SWIFTNESS("minecraft:swiftness"),
SWIFTNESS(NamespaceID.from("minecraft:swiftness")),
LONG_SWIFTNESS("minecraft:long_swiftness"),
LONG_SWIFTNESS(NamespaceID.from("minecraft:long_swiftness")),
STRONG_SWIFTNESS("minecraft:strong_swiftness"),
STRONG_SWIFTNESS(NamespaceID.from("minecraft:strong_swiftness")),
SLOWNESS("minecraft:slowness"),
SLOWNESS(NamespaceID.from("minecraft:slowness")),
LONG_SLOWNESS("minecraft:long_slowness"),
LONG_SLOWNESS(NamespaceID.from("minecraft:long_slowness")),
STRONG_SLOWNESS("minecraft:strong_slowness"),
STRONG_SLOWNESS(NamespaceID.from("minecraft:strong_slowness")),
TURTLE_MASTER("minecraft:turtle_master"),
TURTLE_MASTER(NamespaceID.from("minecraft:turtle_master")),
LONG_TURTLE_MASTER("minecraft:long_turtle_master"),
LONG_TURTLE_MASTER(NamespaceID.from("minecraft:long_turtle_master")),
STRONG_TURTLE_MASTER("minecraft:strong_turtle_master"),
STRONG_TURTLE_MASTER(NamespaceID.from("minecraft:strong_turtle_master")),
WATER_BREATHING("minecraft:water_breathing"),
WATER_BREATHING(NamespaceID.from("minecraft:water_breathing")),
LONG_WATER_BREATHING("minecraft:long_water_breathing"),
LONG_WATER_BREATHING(NamespaceID.from("minecraft:long_water_breathing")),
HEALING("minecraft:healing"),
HEALING(NamespaceID.from("minecraft:healing")),
STRONG_HEALING("minecraft:strong_healing"),
STRONG_HEALING(NamespaceID.from("minecraft:strong_healing")),
HARMING("minecraft:harming"),
HARMING(NamespaceID.from("minecraft:harming")),
STRONG_HARMING("minecraft:strong_harming"),
STRONG_HARMING(NamespaceID.from("minecraft:strong_harming")),
POISON("minecraft:poison"),
POISON(NamespaceID.from("minecraft:poison")),
LONG_POISON("minecraft:long_poison"),
LONG_POISON(NamespaceID.from("minecraft:long_poison")),
STRONG_POISON("minecraft:strong_poison"),
STRONG_POISON(NamespaceID.from("minecraft:strong_poison")),
REGENERATION("minecraft:regeneration"),
REGENERATION(NamespaceID.from("minecraft:regeneration")),
LONG_REGENERATION("minecraft:long_regeneration"),
LONG_REGENERATION(NamespaceID.from("minecraft:long_regeneration")),
STRONG_REGENERATION("minecraft:strong_regeneration"),
STRONG_REGENERATION(NamespaceID.from("minecraft:strong_regeneration")),
STRENGTH("minecraft:strength"),
STRENGTH(NamespaceID.from("minecraft:strength")),
LONG_STRENGTH("minecraft:long_strength"),
LONG_STRENGTH(NamespaceID.from("minecraft:long_strength")),
STRONG_STRENGTH("minecraft:strong_strength"),
STRONG_STRENGTH(NamespaceID.from("minecraft:strong_strength")),
WEAKNESS("minecraft:weakness"),
WEAKNESS(NamespaceID.from("minecraft:weakness")),
LONG_WEAKNESS("minecraft:long_weakness"),
LONG_WEAKNESS(NamespaceID.from("minecraft:long_weakness")),
LUCK("minecraft:luck"),
LUCK(NamespaceID.from("minecraft:luck")),
SLOW_FALLING("minecraft:slow_falling"),
SLOW_FALLING(NamespaceID.from("minecraft:slow_falling")),
LONG_SLOW_FALLING("minecraft:long_slow_falling");
LONG_SLOW_FALLING(NamespaceID.from("minecraft:long_slow_falling"));
private final String namespaceID;
private static final PotionType[] VALUES = values();
private final Key key;
@NotNull
private final NamespaceID id;
PotionType(String namespaceID) {
this.namespaceID = namespaceID;
Registries.potionTypes.put(NamespaceID.from(namespaceID), this);
this.key = Key.key(this.namespaceID);
}
public int getId() {
return ordinal();
}
public String getNamespaceID() {
return namespaceID;
PotionType(@NotNull NamespaceID id) {
this.id = id;
Registries.potionTypes.put(id, this);
}
@Override
@NotNull
public Key key() {
return this.key;
return this.id;
}
public static PotionType fromId(int id) {
if (id >= 0 && id < values().length) {
return values()[id];
public short getId() {
return (short) ordinal();
}
@NotNull
public NamespaceID getNamespaceID() {
return this.id;
}
@Nullable
public static PotionType fromId(short id) {
if(id >= 0 && id < VALUES.length) {
return VALUES[id];
}
return EMPTY;
return null;
}
@NotNull
@Override
public String toString() {
return "[" + this.id + "]";
}
}

View File

@ -1,10 +1,9 @@
// AUTOGENERATED by net.minestom.codegen.RegistriesGenerator
package net.minestom.server.registry;
import java.util.HashMap;
import net.kyori.adventure.key.Key;
import net.minestom.server.entity.EntityType;
import net.minestom.server.fluids.Fluid;
import net.minestom.server.fluid.Fluid;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Enchantment;
import net.minestom.server.item.Material;
@ -12,11 +11,13 @@ 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.stat.StatisticType;
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;
/**
* AUTOGENERATED
*/

View File

@ -1,191 +0,0 @@
package net.minestom.server.stat;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import net.minestom.server.registry.Registries;
import net.minestom.server.utils.NamespaceID;
/**
* //==============================
* // AUTOGENERATED BY EnumGenerator
* //==============================
*/
@SuppressWarnings({"deprecation"})
public enum StatisticType implements Keyed {
LEAVE_GAME("minecraft:leave_game"),
PLAY_ONE_MINUTE("minecraft:play_one_minute"),
TIME_SINCE_DEATH("minecraft:time_since_death"),
TIME_SINCE_REST("minecraft:time_since_rest"),
SNEAK_TIME("minecraft:sneak_time"),
WALK_ONE_CM("minecraft:walk_one_cm"),
CROUCH_ONE_CM("minecraft:crouch_one_cm"),
SPRINT_ONE_CM("minecraft:sprint_one_cm"),
WALK_ON_WATER_ONE_CM("minecraft:walk_on_water_one_cm"),
FALL_ONE_CM("minecraft:fall_one_cm"),
CLIMB_ONE_CM("minecraft:climb_one_cm"),
FLY_ONE_CM("minecraft:fly_one_cm"),
WALK_UNDER_WATER_ONE_CM("minecraft:walk_under_water_one_cm"),
MINECART_ONE_CM("minecraft:minecart_one_cm"),
BOAT_ONE_CM("minecraft:boat_one_cm"),
PIG_ONE_CM("minecraft:pig_one_cm"),
HORSE_ONE_CM("minecraft:horse_one_cm"),
AVIATE_ONE_CM("minecraft:aviate_one_cm"),
SWIM_ONE_CM("minecraft:swim_one_cm"),
STRIDER_ONE_CM("minecraft:strider_one_cm"),
JUMP("minecraft:jump"),
DROP("minecraft:drop"),
DAMAGE_DEALT("minecraft:damage_dealt"),
DAMAGE_DEALT_ABSORBED("minecraft:damage_dealt_absorbed"),
DAMAGE_DEALT_RESISTED("minecraft:damage_dealt_resisted"),
DAMAGE_TAKEN("minecraft:damage_taken"),
DAMAGE_BLOCKED_BY_SHIELD("minecraft:damage_blocked_by_shield"),
DAMAGE_ABSORBED("minecraft:damage_absorbed"),
DAMAGE_RESISTED("minecraft:damage_resisted"),
DEATHS("minecraft:deaths"),
MOB_KILLS("minecraft:mob_kills"),
ANIMALS_BRED("minecraft:animals_bred"),
PLAYER_KILLS("minecraft:player_kills"),
FISH_CAUGHT("minecraft:fish_caught"),
TALKED_TO_VILLAGER("minecraft:talked_to_villager"),
TRADED_WITH_VILLAGER("minecraft:traded_with_villager"),
EAT_CAKE_SLICE("minecraft:eat_cake_slice"),
FILL_CAULDRON("minecraft:fill_cauldron"),
USE_CAULDRON("minecraft:use_cauldron"),
CLEAN_ARMOR("minecraft:clean_armor"),
CLEAN_BANNER("minecraft:clean_banner"),
CLEAN_SHULKER_BOX("minecraft:clean_shulker_box"),
INTERACT_WITH_BREWINGSTAND("minecraft:interact_with_brewingstand"),
INTERACT_WITH_BEACON("minecraft:interact_with_beacon"),
INSPECT_DROPPER("minecraft:inspect_dropper"),
INSPECT_HOPPER("minecraft:inspect_hopper"),
INSPECT_DISPENSER("minecraft:inspect_dispenser"),
PLAY_NOTEBLOCK("minecraft:play_noteblock"),
TUNE_NOTEBLOCK("minecraft:tune_noteblock"),
POT_FLOWER("minecraft:pot_flower"),
TRIGGER_TRAPPED_CHEST("minecraft:trigger_trapped_chest"),
OPEN_ENDERCHEST("minecraft:open_enderchest"),
ENCHANT_ITEM("minecraft:enchant_item"),
PLAY_RECORD("minecraft:play_record"),
INTERACT_WITH_FURNACE("minecraft:interact_with_furnace"),
INTERACT_WITH_CRAFTING_TABLE("minecraft:interact_with_crafting_table"),
OPEN_CHEST("minecraft:open_chest"),
SLEEP_IN_BED("minecraft:sleep_in_bed"),
OPEN_SHULKER_BOX("minecraft:open_shulker_box"),
OPEN_BARREL("minecraft:open_barrel"),
INTERACT_WITH_BLAST_FURNACE("minecraft:interact_with_blast_furnace"),
INTERACT_WITH_SMOKER("minecraft:interact_with_smoker"),
INTERACT_WITH_LECTERN("minecraft:interact_with_lectern"),
INTERACT_WITH_CAMPFIRE("minecraft:interact_with_campfire"),
INTERACT_WITH_CARTOGRAPHY_TABLE("minecraft:interact_with_cartography_table"),
INTERACT_WITH_LOOM("minecraft:interact_with_loom"),
INTERACT_WITH_STONECUTTER("minecraft:interact_with_stonecutter"),
BELL_RING("minecraft:bell_ring"),
RAID_TRIGGER("minecraft:raid_trigger"),
RAID_WIN("minecraft:raid_win"),
INTERACT_WITH_ANVIL("minecraft:interact_with_anvil"),
INTERACT_WITH_GRINDSTONE("minecraft:interact_with_grindstone"),
TARGET_HIT("minecraft:target_hit"),
INTERACT_WITH_SMITHING_TABLE("minecraft:interact_with_smithing_table");
private final String namespaceID;
private final Key key;
StatisticType(String namespaceID) {
this.namespaceID = namespaceID;
Registries.statisticTypes.put(NamespaceID.from(namespaceID), this);
this.key = Key.key(this.namespaceID);
}
public int getId() {
return ordinal();
}
public String getNamespaceID() {
return namespaceID;
}
public Key key() {
return this.key;
}
public static StatisticType fromId(int id) {
if (id >= 0 && id < values().length) {
return values()[id];
}
return null;
}
}

View File

@ -0,0 +1,200 @@
package net.minestom.server.statistic;
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 StatisticGenerator
*/
public enum StatisticType implements Keyed {
LEAVE_GAME(NamespaceID.from("minecraft:leave_game")),
PLAY_ONE_MINUTE(NamespaceID.from("minecraft:play_one_minute")),
TIME_SINCE_DEATH(NamespaceID.from("minecraft:time_since_death")),
TIME_SINCE_REST(NamespaceID.from("minecraft:time_since_rest")),
CROUCH_TIME(NamespaceID.from("minecraft:sneak_time")),
WALK_ONE_CM(NamespaceID.from("minecraft:walk_one_cm")),
CROUCH_ONE_CM(NamespaceID.from("minecraft:crouch_one_cm")),
SPRINT_ONE_CM(NamespaceID.from("minecraft:sprint_one_cm")),
WALK_ON_WATER_ONE_CM(NamespaceID.from("minecraft:walk_on_water_one_cm")),
FALL_ONE_CM(NamespaceID.from("minecraft:fall_one_cm")),
CLIMB_ONE_CM(NamespaceID.from("minecraft:climb_one_cm")),
FLY_ONE_CM(NamespaceID.from("minecraft:fly_one_cm")),
WALK_UNDER_WATER_ONE_CM(NamespaceID.from("minecraft:walk_under_water_one_cm")),
MINECART_ONE_CM(NamespaceID.from("minecraft:minecart_one_cm")),
BOAT_ONE_CM(NamespaceID.from("minecraft:boat_one_cm")),
PIG_ONE_CM(NamespaceID.from("minecraft:pig_one_cm")),
HORSE_ONE_CM(NamespaceID.from("minecraft:horse_one_cm")),
AVIATE_ONE_CM(NamespaceID.from("minecraft:aviate_one_cm")),
SWIM_ONE_CM(NamespaceID.from("minecraft:swim_one_cm")),
STRIDER_ONE_CM(NamespaceID.from("minecraft:strider_one_cm")),
JUMP(NamespaceID.from("minecraft:jump")),
DROP(NamespaceID.from("minecraft:drop")),
DAMAGE_DEALT(NamespaceID.from("minecraft:damage_dealt")),
DAMAGE_DEALT_ABSORBED(NamespaceID.from("minecraft:damage_dealt_absorbed")),
DAMAGE_DEALT_RESISTED(NamespaceID.from("minecraft:damage_dealt_resisted")),
DAMAGE_TAKEN(NamespaceID.from("minecraft:damage_taken")),
DAMAGE_BLOCKED_BY_SHIELD(NamespaceID.from("minecraft:damage_blocked_by_shield")),
DAMAGE_ABSORBED(NamespaceID.from("minecraft:damage_absorbed")),
DAMAGE_RESISTED(NamespaceID.from("minecraft:damage_resisted")),
DEATHS(NamespaceID.from("minecraft:deaths")),
MOB_KILLS(NamespaceID.from("minecraft:mob_kills")),
ANIMALS_BRED(NamespaceID.from("minecraft:animals_bred")),
PLAYER_KILLS(NamespaceID.from("minecraft:player_kills")),
FISH_CAUGHT(NamespaceID.from("minecraft:fish_caught")),
TALKED_TO_VILLAGER(NamespaceID.from("minecraft:talked_to_villager")),
TRADED_WITH_VILLAGER(NamespaceID.from("minecraft:traded_with_villager")),
EAT_CAKE_SLICE(NamespaceID.from("minecraft:eat_cake_slice")),
FILL_CAULDRON(NamespaceID.from("minecraft:fill_cauldron")),
USE_CAULDRON(NamespaceID.from("minecraft:use_cauldron")),
CLEAN_ARMOR(NamespaceID.from("minecraft:clean_armor")),
CLEAN_BANNER(NamespaceID.from("minecraft:clean_banner")),
CLEAN_SHULKER_BOX(NamespaceID.from("minecraft:clean_shulker_box")),
INTERACT_WITH_BREWINGSTAND(NamespaceID.from("minecraft:interact_with_brewingstand")),
INTERACT_WITH_BEACON(NamespaceID.from("minecraft:interact_with_beacon")),
INSPECT_DROPPER(NamespaceID.from("minecraft:inspect_dropper")),
INSPECT_HOPPER(NamespaceID.from("minecraft:inspect_hopper")),
INSPECT_DISPENSER(NamespaceID.from("minecraft:inspect_dispenser")),
PLAY_NOTEBLOCK(NamespaceID.from("minecraft:play_noteblock")),
TUNE_NOTEBLOCK(NamespaceID.from("minecraft:tune_noteblock")),
POT_FLOWER(NamespaceID.from("minecraft:pot_flower")),
TRIGGER_TRAPPED_CHEST(NamespaceID.from("minecraft:trigger_trapped_chest")),
OPEN_ENDERCHEST(NamespaceID.from("minecraft:open_enderchest")),
ENCHANT_ITEM(NamespaceID.from("minecraft:enchant_item")),
PLAY_RECORD(NamespaceID.from("minecraft:play_record")),
INTERACT_WITH_FURNACE(NamespaceID.from("minecraft:interact_with_furnace")),
INTERACT_WITH_CRAFTING_TABLE(NamespaceID.from("minecraft:interact_with_crafting_table")),
OPEN_CHEST(NamespaceID.from("minecraft:open_chest")),
SLEEP_IN_BED(NamespaceID.from("minecraft:sleep_in_bed")),
OPEN_SHULKER_BOX(NamespaceID.from("minecraft:open_shulker_box")),
OPEN_BARREL(NamespaceID.from("minecraft:open_barrel")),
INTERACT_WITH_BLAST_FURNACE(NamespaceID.from("minecraft:interact_with_blast_furnace")),
INTERACT_WITH_SMOKER(NamespaceID.from("minecraft:interact_with_smoker")),
INTERACT_WITH_LECTERN(NamespaceID.from("minecraft:interact_with_lectern")),
INTERACT_WITH_CAMPFIRE(NamespaceID.from("minecraft:interact_with_campfire")),
INTERACT_WITH_CARTOGRAPHY_TABLE(NamespaceID.from("minecraft:interact_with_cartography_table")),
INTERACT_WITH_LOOM(NamespaceID.from("minecraft:interact_with_loom")),
INTERACT_WITH_STONECUTTER(NamespaceID.from("minecraft:interact_with_stonecutter")),
BELL_RING(NamespaceID.from("minecraft:bell_ring")),
RAID_TRIGGER(NamespaceID.from("minecraft:raid_trigger")),
RAID_WIN(NamespaceID.from("minecraft:raid_win")),
INTERACT_WITH_ANVIL(NamespaceID.from("minecraft:interact_with_anvil")),
INTERACT_WITH_GRINDSTONE(NamespaceID.from("minecraft:interact_with_grindstone")),
TARGET_HIT(NamespaceID.from("minecraft:target_hit")),
INTERACT_WITH_SMITHING_TABLE(NamespaceID.from("minecraft:interact_with_smithing_table"));
private static final StatisticType[] VALUES = values();
@NotNull
private final NamespaceID id;
StatisticType(@NotNull NamespaceID id) {
this.id = id;
Registries.statisticTypes.put(id, this);
}
@Override
@NotNull
public Key key() {
return this.id;
}
public short getId() {
return (short) ordinal();
}
@NotNull
public NamespaceID getNamespaceID() {
return this.id;
}
@Nullable
public static StatisticType fromId(short id) {
if(id >= 0 && id < VALUES.length) {
return VALUES[id];
}
return null;
}
@NotNull
@Override
public String toString() {
return "[" + this.id + "]";
}
}

View File

@ -1,31 +0,0 @@
package net.minestom.codegen;
import net.minestom.codegen.blocks.BlockEnumGenerator;
import net.minestom.codegen.enchantment.EnchantmentEnumGenerator;
import net.minestom.codegen.entitytypes.EntityTypeEnumGenerator;
import net.minestom.codegen.fluids.FluidEnumGenerator;
import net.minestom.codegen.items.ItemEnumGenerator;
import net.minestom.codegen.particles.ParticleEnumGenerator;
import net.minestom.codegen.potions.PotionEffectEnumGenerator;
import net.minestom.codegen.potions.PotionEnumGenerator;
import net.minestom.codegen.sounds.SoundEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import java.io.IOException;
public class AllGenerators {
public static void main(String[] args) throws IOException {
BlockEnumGenerator.main(args);
ItemEnumGenerator.main(args); // must be done after block
PotionEnumGenerator.main(args);
PotionEffectEnumGenerator.main(args);
EnchantmentEnumGenerator.main(args);
EntityTypeEnumGenerator.main(args);
SoundEnumGenerator.main(args);
ParticleEnumGenerator.main(args);
StatsEnumGenerator.main(args);
FluidEnumGenerator.main(args);
RegistriesGenerator.main(args);
}
}

View File

@ -1,160 +0,0 @@
package net.minestom.codegen;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
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 java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public abstract class BasicEnumGenerator extends MinestomEnumGenerator<BasicEnumGenerator.Container> {
private static final String MC_DATA_REGISTRIES_PATH = "minecraft_data/reports/registries.json";
/**
* Are IDs linear? Biomes are not for instance.
*/
private final boolean linear;
private NamespaceID defaultEntry;
/**
* True if the enum is linear and start by 1 instead of 0
*/
private boolean incrementOrdinal;
protected BasicEnumGenerator(File targetFolder, boolean linear, boolean incrementOrdinal) throws IOException {
this.linear = linear;
this.incrementOrdinal = incrementOrdinal;
generateTo(targetFolder);
}
protected BasicEnumGenerator(File targetFolder, boolean linear) throws IOException {
this(targetFolder, linear, false);
}
protected BasicEnumGenerator(File targetFolder) throws IOException {
this(targetFolder, true);
}
@Override
protected Collection<Container> compile() throws IOException {
Gson gson = new Gson();
TreeSet<Container> items = new TreeSet<>();
JsonObject root = gson.fromJson(new FileReader(MC_DATA_REGISTRIES_PATH), JsonObject.class);
JsonObject category = root.getAsJsonObject(getCategoryID());
Objects.requireNonNull(category, "Category " + getCategoryID() + " not found in registries.json!");
final JsonObject entries = category.getAsJsonObject("entries");
if (category.has("default")) {
defaultEntry = NamespaceID.from(category.get("default").getAsString());
}
for (var entry : entries.entrySet()) {
final NamespaceID name = NamespaceID.from(entry.getKey());
final int id = entry.getValue().getAsJsonObject().get("protocol_id").getAsInt();
items.add(new Container(id, name));
}
return items;
}
protected abstract String getCategoryID();
@Override
protected void postWrite(EnumGenerator generator) {
ClassName className = ClassName.get(getPackageName(), getClassName());
ParameterSpec idParam = ParameterSpec.builder(TypeName.INT, "id").build();
ParameterSpec[] signature = new ParameterSpec[]{idParam};
if (linear) {
final String ordinalIncrementCondition = incrementOrdinal ? " + 1" : "";
final String ordinalIncrementIndex = incrementOrdinal ? " - 1" : "";
generator.addStaticMethod("fromId", signature, className, code -> {
code.beginControlFlow("if ($N >= 0 && $N < values().length" + ordinalIncrementCondition + ")", idParam, idParam)
.addStatement("return values()[$N" + ordinalIncrementIndex + "]", idParam)
.endControlFlow()
.addStatement("return " + (defaultEntry == null ? "null" : identifier(defaultEntry)));
}
);
} else {
generator.addStaticMethod("fromId", signature, className, code -> {
code.beginControlFlow("for ($T o : values())")
.beginControlFlow("if (o.getId() == id)")
.addStatement("return o")
.endControlFlow()
.endControlFlow()
.addStatement("return " + (defaultEntry == null ? "null" : identifier(defaultEntry)));
}
);
}
}
private String identifier(NamespaceID id) {
return id.getPath().toUpperCase().replace(".", "_"); // block.ambient.cave will be replaced by "BLOCK_AMBIENT_CAVE"
}
@Override
protected List<JavaFile> postGeneration(Collection<Container> items) throws IOException {
return Collections.emptyList();
}
@Override
protected void prepare(EnumGenerator generator) {
generator.addClassAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "{$S}", "deprecation").build());
ClassName registriesClass = ClassName.get(Registries.class);
if (linear) {
generator.setParams(ParameterSpec.builder(ClassName.get(String.class), "namespaceID").build());
generator.addMethod("getId", new ParameterSpec[0], TypeName.INT, code -> code.addStatement("return ordinal()" + (incrementOrdinal ? " + 1" : "")));
} else {
generator.setParams(ParameterSpec.builder(ClassName.get(String.class), "namespaceID").build(), ParameterSpec.builder(TypeName.INT, "id").build());
generator.addMethod("getId", new ParameterSpec[0], TypeName.INT, code -> code.addStatement("return $N", "id"));
}
generator.addMethod("getNamespaceID", new ParameterSpec[0], ClassName.get(String.class), code -> code.addStatement("return $N", "namespaceID"));
generator.appendToConstructor(code -> {
code.addStatement("$T." + CodeGenerator.decapitalize(getClassName()) + "s.put($T.from($N), this)", registriesClass, NamespaceID.class, "namespaceID");
});
// implement Keyed
generator.addSuperinterface(ClassName.get(Keyed.class));
generator.addField(ClassName.get(Key.class), "key", true);
generator.appendToConstructor(code -> code.addStatement("this.key = Key.key(this.namespaceID)"));
generator.addMethod("key", new ParameterSpec[0], ClassName.get(Key.class), code -> code.addStatement("return this.key"));
}
@Override
protected void writeSingle(EnumGenerator generator, Container item) {
if (linear) {
generator.addInstance(identifier(item.name), "\"" + item.name.toString() + "\"");
} else {
generator.addInstance(identifier(item.name), "\"" + item.name.toString() + "\"", item.id);
}
}
static class Container implements Comparable<Container> {
private int id;
private NamespaceID name;
public Container(int id, NamespaceID name) {
this.id = id;
this.name = name;
}
public NamespaceID getName() {
return name;
}
public int getId() {
return id;
}
@Override
public int compareTo(Container o) {
return Integer.compare(id, o.id);
}
}
}

View File

@ -1,35 +0,0 @@
package net.minestom.codegen;
import com.squareup.javapoet.JavaFile;
import org.slf4j.Logger;
import java.io.*;
import java.util.List;
/**
* Interface representing a code generator
*/
public interface CodeGenerator {
/**
* Generates the Java code
* @return
*/
List<JavaFile> generate() throws IOException;
default void generateTo(File targetFolder) throws IOException {
List<JavaFile> code = generate();
for(JavaFile file : code) {
getLogger().debug("Writing file: "+file.packageName+"."+file.typeSpec.name);
file.writeTo(targetFolder);
}
}
Logger getLogger();
static String decapitalize(String text) {
char first = text.charAt(0);
return ""+Character.toLowerCase(first)+text.substring(1);
}
}

View File

@ -1,16 +0,0 @@
package net.minestom.codegen;
import com.squareup.javapoet.ClassName;
public class ConstructorLambda {
private final ClassName className;
public ConstructorLambda(ClassName className) {
this.className = className;
}
public ClassName getClassName() {
return className;
}
}

View File

@ -1,258 +0,0 @@
package net.minestom.codegen;
import com.squareup.javapoet.*;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
/**
* Helper class to generate a .java enum
*/
public class EnumGenerator implements CodeGenerator {
private final static Logger LOGGER = LoggerFactory.getLogger(EnumGenerator.class);
private static final String COMMENT = "//==============================\n// AUTOGENERATED BY " + EnumGenerator.class.getSimpleName() + "\n//==============================";
private final String enumName;
private ParameterSpec[] parameters;
private List<TypeName> superinterfaces = new LinkedList<>();
private List<Method> methods = new LinkedList<>();
private List<Field> staticFields = new LinkedList<>();
private List<Instance> instances = new LinkedList<>();
private List<Pair<Field, Boolean>> fields = new LinkedList<>();
private List<Field> hardcodedFields = new LinkedList<>();
private List<AnnotationSpec> annotations = new LinkedList<>();
private String enumPackage;
private CodeBlock staticBlock;
private List<Consumer<CodeBlock.Builder>> constructorEnds = new LinkedList<>();
public EnumGenerator(String packageName, String enumName) {
this.enumPackage = packageName;
parameters = new ParameterSpec[0];
this.enumName = enumName;
}
public void addSuperinterface(TypeName typeNames) {
superinterfaces.add(typeNames);
}
public void setParams(ParameterSpec... parameters) {
this.parameters = parameters;
}
public void addMethod(String name, ParameterSpec[] signature, TypeName returnType, Consumer<CodeBlock.Builder> code) {
methods.add(new Method(false, name, signature, returnType, code, false));
}
public void addVarargMethod(String name, ParameterSpec[] signature, TypeName returnType, Consumer<CodeBlock.Builder> code) {
methods.add(new Method(false, name, signature, returnType, code, true));
}
public void addStaticMethod(String name, ParameterSpec[] signature, TypeName returnType, Consumer<CodeBlock.Builder> code) {
methods.add(new Method(true, name, signature, returnType, code, false));
}
public void addStaticField(TypeName type, String name, String value) {
staticFields.add(new Field(type, name, value));
}
public void addInstance(String name, Object... parameters) {
instances.add(new Instance(name, parameters));
}
public List<JavaFile> generate() {
TypeSpec.Builder enumClass = TypeSpec.enumBuilder(ClassName.get(enumPackage, enumName)).addModifiers(Modifier.PUBLIC);
enumClass.addJavadoc(COMMENT);
for (AnnotationSpec annotation : annotations) {
enumClass.addAnnotation(annotation);
}
for (Instance instance : instances) {
StringBuilder format = new StringBuilder();
for (int i = 0; i < instance.parameters.length; i++) {
if (i != 0) {
format.append(", ");
}
if (instance.parameters[i] instanceof ConstructorLambda) {
instance.parameters[i] = ((ConstructorLambda) instance.parameters[i]).getClassName();
format.append("$T::new");
} else {
format.append("$L");
}
}
// generate instances
TypeSpec arguments = TypeSpec.anonymousClassBuilder(format.toString(), instance.parameters).build();
enumClass.addEnumConstant(instance.name, arguments);
}
// add superinterfaces
enumClass.addSuperinterfaces(superinterfaces);
if (staticBlock != null) {
enumClass.addStaticBlock(staticBlock);
}
// generate properties & constructor
if (parameters.length != 0) {
// properties
for (ParameterSpec property : parameters) {
enumClass.addField(FieldSpec.builder(property.type, property.name)
.addModifiers(Modifier.PRIVATE, Modifier.FINAL)
.addAnnotations(property.annotations)
.build());
}
for (Field field : staticFields) {
enumClass.addField(FieldSpec.builder(field.type, field.name)
.initializer("$L", field.value)
.addModifiers(Modifier.PRIVATE, Modifier.FINAL, Modifier.STATIC)
.build());
}
// hard coded fields
for (Field hardcoded : hardcodedFields) {
enumClass.addField(FieldSpec.builder(hardcoded.type, hardcoded.name)
.initializer("$L", hardcoded.value)
.addModifiers(Modifier.PRIVATE)
.build());
}
// normal fields
for (Pair<Field, Boolean> field : fields) {
FieldSpec.Builder builder = FieldSpec.builder(field.getLeft().type, field.getLeft().name)
.addModifiers(Modifier.PRIVATE);
if (field.getRight()) {
builder.addModifiers(Modifier.FINAL);
}
enumClass.addField(builder.build());
}
// constructor
MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder();
for (ParameterSpec param : parameters) {
constructorBuilder.addParameter(param);
// property assignment
constructorBuilder.addStatement("this.$N = $N", param.name, param.name);
}
CodeBlock.Builder generatorEnd = CodeBlock.builder();
constructorEnds.forEach(b -> b.accept(generatorEnd));
constructorBuilder.addCode(generatorEnd.build());
enumClass.addMethod(constructorBuilder.build());
}
// generate methods
for (Method m : methods) {
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(m.name);
if (m.isStatic) {
methodBuilder.addModifiers(Modifier.STATIC);
}
methodBuilder.addModifiers(Modifier.PUBLIC);
methodBuilder.returns(m.returnType);
if (m.vararg) {
methodBuilder.varargs(true);
}
for (ParameterSpec parameter : m.signature) {
methodBuilder.addParameter(parameter);
}
CodeBlock.Builder builder = CodeBlock.builder();
m.code.accept(builder);
methodBuilder.addCode(builder.build());
enumClass.addMethod(methodBuilder.build());
}
JavaFile file = JavaFile.builder(enumPackage, enumClass.build())
.skipJavaLangImports(true)
.indent(" ")
.build();
return Collections.singletonList(file);
}
public void setStaticInitBlock(CodeBlock staticBlock) {
this.staticBlock = staticBlock;
}
public void appendToConstructor(Consumer<CodeBlock.Builder> constructorEnding) {
constructorEnds.add(constructorEnding);
}
public void addField(TypeName type, String name, boolean isFinal) {
fields.add(Pair.of(new Field(type, name), isFinal));
}
public void addHardcodedField(TypeName type, String name, String value) {
hardcodedFields.add(new Field(type, name, value));
}
public void addClassAnnotation(AnnotationSpec annotation) {
annotations.add(annotation);
}
public String getPackage() {
return enumPackage;
}
public String getEnumName() {
return enumName;
}
@Override
public Logger getLogger() {
return LOGGER;
}
private static class Method {
private final boolean isStatic;
private String name;
private ParameterSpec[] signature;
private TypeName returnType;
private Consumer<CodeBlock.Builder> code;
private boolean vararg;
private Method(boolean isStatic, String name, ParameterSpec[] signature, TypeName returnType, Consumer<CodeBlock.Builder> code, boolean vararg) {
this.isStatic = isStatic;
this.name = name;
this.signature = signature;
this.returnType = returnType;
this.code = code;
this.vararg = vararg;
}
}
private static class Field {
private TypeName type;
private String name;
private String value;
public Field(TypeName type, String name) {
this(type, name, null);
}
public Field(TypeName type, String name, String value) {
this.type = type;
this.name = name;
this.value = value;
}
}
private static class Instance {
private String name;
private Object[] parameters;
private Instance(String name, Object[] parameters) {
this.name = name;
this.parameters = parameters;
}
}
}

View File

@ -1,112 +0,0 @@
package net.minestom.codegen;
import com.squareup.javapoet.JavaFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
*
* @param <Container> the type of container to pass between the extraction and generation phases
*/
public abstract class MinestomEnumGenerator<Container> implements CodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(MinestomEnumGenerator.class);
public static final String DEFAULT_TARGET_PATH = "src/autogenerated/java";
public static final String PRISMARINE_JS_DATA_PATHS = "prismarine-minecraft-data/data/dataPaths.json";
public static final String BURGER_URL_BASE_URL = "https://pokechu22.github.io/Burger/";
/**
* Package name with '.' replaced by '/'
* @return
*/
protected String getRelativeFolderPath() {
return getPackageName().replace(".", "/");
}
@Override
public List<JavaFile> generate() throws IOException {
EnumGenerator generator = new EnumGenerator(getPackageName(), getClassName());
prepare(generator);
Collection<Container> items = compile();
for(Container c : items) {
writeSingle(generator, c);
}
postWrite(generator);
List<JavaFile> list = new LinkedList<>(generator.generate());
list.addAll(postGeneration(items));
return list;
}
/**
* Called after writing all compiled items into the enum generator
* @param generator
*/
protected abstract void postWrite(EnumGenerator generator);
/**
* Called after code generation (only if generated through a {@link #generateTo(File)} call). Can be used to generate additional files
* @param items
*/
protected abstract List<JavaFile> postGeneration(Collection<Container> items) throws IOException;
/**
* Package in which to generate the enum
* @return
*/
public abstract String getPackageName();
/**
* Name of the enum to generate
* @return
*/
public abstract String getClassName();
/**
* Extracts and gather information about the enum we want to generate.
* @throws IOException if an error occurred during data gathering
* @return
*/
protected abstract Collection<Container> compile() throws IOException;
/**
* Prepare the EnumGenerator (package name, class names, imports, constructor...)
* @param generator
*/
protected abstract void prepare(EnumGenerator generator);
/**
* Write an entry to the generator. The order in which items are provided (via different call) is considered to be
* the order in which they will presented in the enum
* @param generator
* @param item
*/
protected abstract void writeSingle(EnumGenerator generator, Container item);
/**
* Converts a snake case identifier (some_long_name) to a capitalized camel case identifier (SomeLongName)
* @param identifier
* @return
*/
protected String snakeCaseToCapitalizedCamelCase(String identifier) {
boolean capitalizeNext = true;
StringBuilder result = new StringBuilder();
char[] chars = identifier.toCharArray();
for (int i = 0; i < identifier.length(); i++) {
char currentCharacter = chars[i];
if(capitalizeNext) {
result.append(Character.toUpperCase(currentCharacter));
capitalizeNext = false;
} else if(currentCharacter == '_') {
capitalizeNext = true;
} else {
result.append(currentCharacter);
}
}
return result.toString();
}
}

View File

@ -1,35 +0,0 @@
package net.minestom.codegen;
import java.io.File;
public class PrismarinePaths {
private String blocks;
private String biomes;
private String effects;
private String items;
private String recipes;
private String instruments;
private String materials;
private String entities;
private String protocol;
private String windows;
private String version;
private String language;
public File getBlockFile() {
return getFile(blocks, "blocks");
}
public File getItemsFile() {
return getFile(items, "items");
}
public File getBiomesFile() {
return getFile(biomes, "biomes");
}
public File getFile(String path, String type) {
return new File("prismarine-minecraft-data/data/" + path + "/" + type + ".json");
}
}

View File

@ -1,192 +0,0 @@
package net.minestom.codegen;
import com.squareup.javapoet.*;
import net.kyori.adventure.key.Key;
import net.minestom.server.entity.EntityType;
import net.minestom.server.fluids.Fluid;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Enchantment;
import net.minestom.server.item.Material;
import net.minestom.server.particle.Particle;
import net.minestom.server.potion.PotionEffect;
import net.minestom.server.potion.PotionType;
import net.minestom.server.registry.ResourceGatherer;
import net.minestom.server.sound.SoundEvent;
import net.minestom.server.stat.StatisticType;
import net.minestom.server.utils.NamespaceID;
import org.apache.commons.lang3.tuple.ImmutablePair;
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.IOException;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import static net.minestom.codegen.MinestomEnumGenerator.DEFAULT_TARGET_PATH;
/**
* Generates the Registries class, which contains methods to get items/blocks/biomes/etc. from a NamespaceID
*/
public class RegistriesGenerator implements CodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(RegistriesGenerator.class);
private static final ImmutablePair<String, String>[] registries = new ImmutablePair[]{
new ImmutablePair<>(Block.class.getCanonicalName(), "AIR"),
new ImmutablePair<>(Material.class.getCanonicalName(), "AIR"),
new ImmutablePair<>(Enchantment.class.getCanonicalName(), null),
new ImmutablePair<>(EntityType.class.getCanonicalName(), null),
new ImmutablePair<>(Particle.class.getCanonicalName(), null),
new ImmutablePair<>(PotionType.class.getCanonicalName(), null),
new ImmutablePair<>(PotionEffect.class.getCanonicalName(), null),
new ImmutablePair<>(SoundEvent.class.getCanonicalName(), null),
new ImmutablePair<>(StatisticType.class.getCanonicalName(), null),
new ImmutablePair<>(Fluid.class.getCanonicalName(), "EMPTY"),
};
@Override
public List<JavaFile> generate() throws IOException {
TypeSpec.Builder registriesClass = TypeSpec.classBuilder(ClassName.get("net.minestom.server.registry", "Registries"))
.addModifiers(Modifier.FINAL, Modifier.PUBLIC)
.addJavadoc("AUTOGENERATED");
FieldSpec[] fields = new FieldSpec[registries.length];
// Hashmaps
for (int i = 0; i < registries.length; i++) {
ClassName type = ClassName.bestGuess(registries[i].left);
String simpleType = type.simpleName();
FieldSpec field = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(HashMap.class), ClassName.get(NamespaceID.class), type), CodeGenerator.decapitalize(simpleType) + "s")
.addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC)
.addJavadoc("Should only be used for internal code, please use the get* methods.")
.addAnnotation(Deprecated.class)
.initializer("new HashMap<>()")
.build();
fields[i] = field;
registriesClass.addField(field);
}
// accessor methods
for (int i = 0; i < registries.length; i++) {
ClassName type = ClassName.bestGuess(registries[i].left);
String simpleType = type.simpleName();
String defaultValue = registries[i].right;
// Example:
/*
/** Returns 'AIR' if none match
public static Block getBlock(String id) {
return getBlock(NamespaceID.from(id));
}
/** Returns 'AIR' if none match
public static Block getBlock(NamespaceID id) {
return blocks.getOrDefault(id, AIR);
}
*/
StringBuilder comment = new StringBuilder("Returns the corresponding ");
comment.append(simpleType).append(" matching the given id. Returns ");
if (defaultValue != null) {
comment.append('\'').append(defaultValue).append('\'');
} else {
comment.append("null");
}
comment.append(" if none match.");
ParameterSpec namespaceIDParam = ParameterSpec.builder(ClassName.get(NamespaceID.class), "id")
.build();
ParameterSpec keyIDParam = ParameterSpec.builder(ClassName.get(Key.class), "key").build();
CodeBlock.Builder code = CodeBlock.builder();
Class<? extends Annotation> annotation;
if (defaultValue != null) {
annotation = NotNull.class;
code.addStatement("return $N.getOrDefault($N, $T.$N)", fields[i], namespaceIDParam, type, defaultValue);
} else {
annotation = Nullable.class;
code.addStatement("return $N.get($N)", fields[i], namespaceIDParam);
}
// string variant
ParameterSpec idParam = ParameterSpec.builder(ClassName.get(String.class), "id")
.build();
MethodSpec idMethod = MethodSpec.methodBuilder("get" + simpleType)
.returns(type)
.addAnnotation(annotation)
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.addParameter(idParam)
.addStatement("return get$N(NamespaceID.from($N))", simpleType, idParam)
.addJavadoc(comment.toString())
.build();
registriesClass.addMethod(idMethod);
// NamespaceID variant
registriesClass.addMethod(MethodSpec.methodBuilder("get" + simpleType)
.returns(type)
.addAnnotation(annotation)
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.addParameter(namespaceIDParam)
.addCode(code.build())
.addJavadoc(comment.toString())
.build());
// Key variant
registriesClass.addMethod(MethodSpec.methodBuilder("get" + simpleType)
.returns(type)
.addAnnotation(annotation)
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.addParameter(keyIDParam)
.addStatement("return get$N(NamespaceID.from($N))", simpleType, keyIDParam)
.addJavadoc(comment.toString().replace(" id.", " key."))
.build());
}
JavaFile file = JavaFile.builder("net.minestom.server.registry", registriesClass.build())
.addFileComment("AUTOGENERATED by " + getClass().getCanonicalName())
.indent(" ")
.skipJavaLangImports(true)
.build();
return Collections.singletonList(file);
}
public static void main(String[] args) throws IOException {
// copy-pasted from BlockEnumGenerator, to stay consistent in the order of arguments
String targetVersion;
if (args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if (args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
new RegistriesGenerator().generateTo(targetFolder);
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,33 +0,0 @@
package net.minestom.codegen;
import java.io.File;
import java.util.Arrays;
public class TagGen {
public static void main(String[] args) {
StringBuilder out = new StringBuilder();
File workingDir = new File("minecraft_data/data/minecraft/tags/blocks");
Arrays.stream(workingDir.listFiles()).forEach((file) -> {
out.append("addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from(\"");
out.append(file.getName(), 0, file.getName().length()-5).append("\"));\n");
});
workingDir = new File("minecraft_data/data/minecraft/tags/entity_types");
Arrays.stream(workingDir.listFiles()).forEach((file) -> {
out.append("addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from(\"");
out.append(file.getName(), 0, file.getName().length()-5).append("\"));\n");
});
workingDir = new File("minecraft_data/data/minecraft/tags/fluids");
Arrays.stream(workingDir.listFiles()).forEach((file) -> {
out.append("addRequiredTag(Tag.BasicTypes.FLUIDS, NamespaceID.from(\"");
out.append(file.getName(), 0, file.getName().length()-5).append("\"));\n");
});
workingDir = new File("minecraft_data/data/minecraft/tags/items");
Arrays.stream(workingDir.listFiles()).forEach((file) -> {
out.append("addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from(\"");
out.append(file.getName(), 0, file.getName().length()-5).append("\"));\n");
});
System.out.println(out.toString());
}
}

View File

@ -1,150 +0,0 @@
package net.minestom.codegen.blocks;
import net.minestom.server.utils.NamespaceID;
import java.util.List;
import java.util.Map;
public class BlockContainer implements Comparable<BlockContainer> {
private int ordinal;
private NamespaceID id;
private double hardness;
private double resistance;
private BlockState defaultState;
private boolean isSolid;
private boolean isAir;
private List<BlockState> states;
private boolean isMushroom;
private boolean isLiquid;
private boolean isFlower;
private boolean isFlowerPot;
private boolean isCoral;
private NamespaceID blockEntity;
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;
}
public int getOrdinal() {
return ordinal;
}
public BlockState getDefaultState() {
return defaultState;
}
public List<BlockState> getStates() {
return states;
}
public NamespaceID getId() {
return id;
}
public boolean isAir() {
return isAir;
}
public boolean isLiquid() {
return isLiquid;
}
public boolean isMushroom() {
return isMushroom;
}
public boolean isSolid() {
return isSolid;
}
public double getHardness() {
return hardness;
}
public double getResistance() {
return resistance;
}
public NamespaceID getBlockEntityName() {
return blockEntity;
}
public BlockContainer setLiquid() {
isLiquid = true;
return this;
}
public BlockContainer setMushroom() {
isMushroom = true;
return this;
}
public BlockContainer setSolid() {
isSolid = true;
return this;
}
public BlockContainer setAir() {
isAir = true;
return this;
}
@Override
public String toString() {
return "blocks.BlockContainer{" +
"id=" + id +
", hardness=" + hardness +
", resistance=" + resistance +
", defaultState=" + defaultState +
", isSolid=" + isSolid +
", isAir=" + isAir +
", states=" + states +
", isMushroom=" + isMushroom +
", isLiquid=" + isLiquid +
", isFlower=" + isFlower +
", isFlowerPot=" + isFlowerPot +
", isCoral=" + isCoral +
", blockEntity=" + blockEntity +
'}';
}
@Override
public int compareTo(BlockContainer o) {
return Integer.compare(ordinal, o.ordinal);
}
public static class BlockState {
private short id;
private Map<String, String> properties;
public BlockState(short id, Map<String, String> properties) {
this.id = id;
this.properties = properties;
}
public short getId() {
return id;
}
public Map<String, String> getProperties() {
return properties;
}
@Override
public String toString() {
return "BlockState{" +
"id=" + id +
", properties=" + properties +
'}';
}
}
}

View File

@ -1,398 +0,0 @@
package net.minestom.codegen.blocks;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import net.minestom.codegen.EnumGenerator;
import net.minestom.codegen.MinestomEnumGenerator;
import net.minestom.codegen.PrismarinePaths;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockAlternative;
import net.minestom.server.registry.Registries;
import net.minestom.server.registry.ResourceGatherer;
import net.minestom.server.utils.NamespaceID;
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.*;
import java.net.URL;
import java.util.*;
/**
* Generates a Block enum containing all data about blocks
*/
public class BlockEnumGenerator extends MinestomEnumGenerator<BlockContainer> {
private static final Logger LOGGER = LoggerFactory.getLogger(BlockEnumGenerator.class);
public static final String MC_DATA_BLOCKS_PATH = "minecraft_data/reports/blocks.json";
private final String targetVersion;
private final File targetFolder;
private final CodeBlock.Builder staticBlock = CodeBlock.builder();
public static void main(String[] args) throws IOException {
String targetVersion;
if (args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if (args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
new BlockEnumGenerator(targetVersion, targetFolder);
}
private BlockEnumGenerator(String targetVersion, File targetFolder) throws IOException {
this.targetVersion = targetVersion;
this.targetFolder = targetFolder;
generateTo(targetFolder);
}
/**
* Compiles all block information in a single location
*
* @param dataBlocks
* @param prismarineJSBlocks
* @param burgerBlocks
*/
private Collection<BlockContainer> compile(List<DataReportBlock> dataBlocks, List<PrismarineJSBlock> prismarineJSBlocks, List<BurgerBlock> burgerBlocks) {
TreeSet<BlockContainer> blocks = new TreeSet<>(BlockContainer::compareTo);
// ensure the 3 list have the same length and order
dataBlocks.sort(Comparator.comparing(block -> block.name.toString()));
prismarineJSBlocks.sort(Comparator.comparing(block -> NamespaceID.from(block.name).toString()));
burgerBlocks.sort(Comparator.comparing(block -> NamespaceID.from(block.text_id).toString()));
// if one of these tests fail, you probably forgot to clear the minecraft_data cache before launching this program
if (dataBlocks.size() != prismarineJSBlocks.size()) {
throw new Error("minecraft_data block count is different from PrismarineJS count! Try clearing the minecraft_data cache");
}
if (prismarineJSBlocks.size() != burgerBlocks.size()) {
throw new Error("Burger's block count is different from PrismarineJS count! Try clearing the minecraft_data cache");
}
for (int i = 0; i < dataBlocks.size(); i++) {
DataReportBlock data = dataBlocks.get(i);
PrismarineJSBlock prismarine = prismarineJSBlocks.get(i);
BurgerBlock burger = burgerBlocks.get(i);
assert data.name.getPath().equals(prismarine.name) && prismarine.name.equalsIgnoreCase(burger.text_id);
List<BlockContainer.BlockState> states = new LinkedList<>();
for (DataReportBlock.BlockState s : data.states) {
states.add(new BlockContainer.BlockState(s.id, s.properties));
}
BlockContainer.BlockState defaultState = new BlockContainer.BlockState(data.defaultState.id, data.defaultState.properties);
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();
}
boolean isAir = data.name.equals(NamespaceID.from("minecraft:air")) || data.name.getPath().endsWith("_air");
if (isAir) {
block.setAir();
}
blocks.add(block);
}
return blocks;
}
/**
* Extracts block information from Burger
*
* @param gson
* @param url
* @return
* @throws IOException
*/
private 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 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 : blockMap.entrySet()) {
BurgerBlock block = gson.fromJson(entry.getValue(), BurgerBlock.class);
block.blockEntity = block2entityMap.get(block.text_id);
blocks.add(block);
}
return blocks;
}
}
/**
* Extract block information from PrismarineJS (submodule of Minestom)
*
* @param gson
* @param blockFile
* @return
* @throws IOException
*/
private List<PrismarineJSBlock> parseBlocksFromPrismarineJS(Gson gson, File blockFile) throws IOException {
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(blockFile))) {
PrismarineJSBlock[] blocks = gson.fromJson(bufferedReader, PrismarineJSBlock[].class);
return Arrays.asList(blocks);
}
}
/**
* Extract block information from reports generated by the data extractor present in minecraft_server.jar
*
* @param gson
* @param path
* @return
*/
private List<DataReportBlock> parseBlocksFromMCData(Gson gson, String path) {
List<DataReportBlock> blocks = new LinkedList<>();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
JsonObject obj = gson.fromJson(bufferedReader, JsonObject.class);
for (var entry : obj.entrySet()) {
NamespaceID id = NamespaceID.from(entry.getKey());
JsonElement blockInfo = entry.getValue();
DataReportBlock block = gson.fromJson(blockInfo, DataReportBlock.class);
block.bindDefaultState();
block.name = id;
blocks.add(block);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return blocks;
}
@Override
public String getPackageName() {
return "net.minestom.server.instance.block";
}
@Override
public String getClassName() {
return "Block";
}
@Override
protected Collection<BlockContainer> compile() throws IOException {
Gson gson = new Gson();
// load report blocks and block states
LOGGER.debug("Loading information from data extraction");
List<DataReportBlock> dataBlocks = parseBlocksFromMCData(gson, MC_DATA_BLOCKS_PATH);
// load properties from Prismarine
LOGGER.debug("Finding path for PrismarineJS blocks");
JsonObject dataPaths = gson.fromJson(new BufferedReader(new FileReader(PRISMARINE_JS_DATA_PATHS)), JsonObject.class);
JsonObject pathsJson = dataPaths.getAsJsonObject("pc").getAsJsonObject(targetVersion);
PrismarinePaths paths = gson.fromJson(pathsJson, PrismarinePaths.class);
LOGGER.debug("Loading PrismarineJS blocks data");
List<PrismarineJSBlock> prismarineJSBlocks = parseBlocksFromPrismarineJS(gson, paths.getBlockFile());
LOGGER.debug("Loading Burger blocks data (requires Internet connection)");
List<BurgerBlock> burgerBlocks = parseBlocksFromBurger(gson, BURGER_URL_BASE_URL + targetVersion + ".json");
LOGGER.debug("Compiling information");
return compile(dataBlocks, prismarineJSBlocks, burgerBlocks);
}
@Override
protected void prepare(EnumGenerator generator) {
ClassName className = ClassName.get(getPackageName(), getClassName());
generator.addClassAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "{$S}", "deprecation").build());
generator.setParams(
ParameterSpec.builder(String.class, "namespaceID").addAnnotation(NotNull.class).build(),
ParameterSpec.builder(TypeName.SHORT, "defaultID").build(),
ParameterSpec.builder(TypeName.DOUBLE, "hardness").build(),
ParameterSpec.builder(TypeName.DOUBLE, "resistance").build(),
ParameterSpec.builder(TypeName.BOOLEAN, "isAir").build(),
ParameterSpec.builder(TypeName.BOOLEAN, "isSolid").build(),
ParameterSpec.builder(NamespaceID.class, "blockEntity").addAnnotation(Nullable.class).build(),
ParameterSpec.builder(TypeName.BOOLEAN, "singleState").build()
);
generator.addHardcodedField(ParameterizedTypeName.get(List.class, BlockAlternative.class), "alternatives", "new java.util.ArrayList<>()");
generator.addMethod("getBlockId", new ParameterSpec[0], TypeName.SHORT, code -> code.addStatement("return defaultID"));
generator.addMethod("getName", new ParameterSpec[0], ClassName.get(String.class), code -> code.addStatement("return namespaceID"));
generator.addMethod("isAir", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return isAir"));
generator.addMethod("hasBlockEntity", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return blockEntity != null"));
generator.addMethod("getBlockEntityName", new ParameterSpec[0], ClassName.get(NamespaceID.class), code -> code.addStatement("return blockEntity"));
generator.addMethod("isSolid", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return isSolid"));
generator.addMethod("isLiquid", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return this == WATER || this == LAVA"));
generator.addMethod("getHardness", new ParameterSpec[0], TypeName.DOUBLE, code -> code.addStatement("return hardness"));
generator.addMethod("getResistance", new ParameterSpec[0], TypeName.DOUBLE, code -> code.addStatement("return resistance"));
generator.addMethod("breaksInstantaneously", new ParameterSpec[0], TypeName.BOOLEAN, code -> code.addStatement("return hardness == 0"));
generator.addMethod("addBlockAlternative", new ParameterSpec[]{ParameterSpec.builder(BlockAlternative.class, "alternative").build()}, TypeName.VOID, code -> {
code.addStatement("alternatives.add(alternative)")
.addStatement("$T.blocks[alternative.getId()] = this", ClassName.get("net.minestom.server.instance.block", "BlockArray"));
});
generator.addMethod("getAlternative", new ParameterSpec[]{ParameterSpec.builder(TypeName.SHORT, "blockId").build()}, ClassName.get(BlockAlternative.class), code -> {
code.beginControlFlow("for($T alt : alternatives)", BlockAlternative.class)
.beginControlFlow("if(alt.getId() == blockId)")
.addStatement("return alt")
.endControlFlow()
.endControlFlow()
.addStatement("return null");
});
generator.addMethod("getAlternatives", new ParameterSpec[0], ParameterizedTypeName.get(List.class, BlockAlternative.class), code -> code.addStatement("return alternatives"));
generator.addVarargMethod("withProperties", new ParameterSpec[]{ParameterSpec.builder(String[].class, "properties").build()}, TypeName.SHORT, code -> {
code.beginControlFlow("for($T alt : alternatives)", BlockAlternative.class)
.beginControlFlow("if($T.equals(alt.getProperties(), properties))", Arrays.class)
.addStatement("return alt.getId()")
.endControlFlow()
.endControlFlow()
.addStatement("return defaultID");
});
generator.addStaticMethod("fromStateId", new ParameterSpec[]{ParameterSpec.builder(TypeName.SHORT, "blockStateId").build()}, className, code -> code.addStatement("return $T.blocks[blockStateId]", ClassName.get("net.minestom.server.instance.block", "BlockArray")));
generator.appendToConstructor(code -> {
code.beginControlFlow("if(singleState)")
.addStatement("addBlockAlternative(new BlockAlternative(defaultID))")
.endControlFlow()
.addStatement("$T.blocks.put($T.from(namespaceID), this)", Registries.class, NamespaceID.class);
});
// implement Keyed
generator.addSuperinterface(ClassName.get(Keyed.class));
generator.addField(ClassName.get(Key.class), "key", true);
generator.appendToConstructor(code -> code.addStatement("this.key = Key.key(this.namespaceID)"));
generator.addMethod("key", new ParameterSpec[0], ClassName.get(Key.class), code -> code.addStatement("return this.key"));
}
@Override
protected void writeSingle(EnumGenerator generator, BlockContainer block) {
String instanceName = block.getId().getPath().toUpperCase();
generator.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",
block.getStates().size() == 1 // used to avoid duplicates inside the 'alternatives' field due to both constructor addition and subclasses initStates()
);
if (block.getStates().size() > 1) {
String blockName = snakeCaseToCapitalizedCamelCase(block.getId().getPath());
blockName = blockName.replace("_", "");
staticBlock.addStatement("$T.initStates()", ClassName.get(getPackageName()+".states", blockName));
}
}
@Override
protected List<JavaFile> postGeneration(Collection<BlockContainer> items) throws IOException {
List<JavaFile> additionalFiles = new LinkedList<>();
TypeSpec blockArrayClass = TypeSpec.classBuilder("BlockArray")
.addModifiers(Modifier.FINAL)
.addField(FieldSpec.builder(Block[].class, "blocks").initializer("new Block[Short.MAX_VALUE]").addModifiers(Modifier.STATIC, Modifier.FINAL).build())
.build();
additionalFiles.add(JavaFile.builder(getPackageName(), blockArrayClass).indent(" ").skipJavaLangImports(true).build());
LOGGER.debug("Writing subclasses for block alternatives...");
final String warningComment = "Completely internal. DO NOT USE. IF YOU ARE A USER AND FACE A PROBLEM WHILE USING THIS CODE, THAT'S ON YOU.";
final AnnotationSpec internalUseAnnotation = AnnotationSpec.builder(Deprecated.class).addMember("since", "$S", "forever").addMember("forRemoval", "$L", false).build();
for(BlockContainer block : items) {
// do not add alternative for default states. This will be added by default inside the constructor
if (block.getStates().size() > 1) {
String blockName = snakeCaseToCapitalizedCamelCase(block.getId().getPath());
blockName = blockName.replace("_", "");
TypeSpec.Builder subclass = TypeSpec.classBuilder(blockName)
.addAnnotation(internalUseAnnotation)
.addJavadoc(warningComment)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
MethodSpec.Builder initStatesMethod = MethodSpec.methodBuilder("initStates")
.returns(TypeName.VOID)
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.addAnnotation(internalUseAnnotation)
.addJavadoc(warningComment);
for (BlockContainer.BlockState state : block.getStates()) {
if (state == block.getDefaultState())
continue;
// generate BlockAlternative instance that will be used to lookup block alternatives
StringBuilder propertyList = new StringBuilder();
// add block state properties if applicable
if (state.getProperties() != null) {
for (var property : state.getProperties().entrySet()) {
propertyList.append(", ");
propertyList.append("\"").append(property.getKey()).append("=").append(property.getValue()).append("\"");
}
}
initStatesMethod.addStatement("$T.$N.addBlockAlternative(new $T((short) $L"+propertyList+"))", Block.class, block.getId().getPath().toUpperCase(), BlockAlternative.class, state.getId());
}
subclass.addMethod(initStatesMethod.build());
staticBlock.addStatement("$T.initStates()", ClassName.get(getPackageName()+".states", blockName));
additionalFiles.add(JavaFile.builder(getPackageName()+".states", subclass.build())
.indent(" ")
.skipJavaLangImports(true)
.build());
}
}
return additionalFiles;
}
@Override
protected void postWrite(EnumGenerator generator) {
generator.setStaticInitBlock(staticBlock.build());
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,18 +0,0 @@
package net.minestom.codegen.blocks;
public class BurgerBlock {
String text_id;
double resistance;
// from tileentities
BurgerTileEntity blockEntity;
@Override
public String toString() {
return "blocks.BurgerBlock{" +
"text_id='" + text_id + '\'' +
", resistance=" + resistance +
'}';
}
}

View File

@ -1,9 +0,0 @@
package net.minestom.codegen.blocks;
public class BurgerTileEntity {
String[] blocks;
String name;
int network_id;
}

View File

@ -1,55 +0,0 @@
package net.minestom.codegen.blocks;
import com.google.gson.annotations.SerializedName;
import net.minestom.server.utils.NamespaceID;
import java.util.Arrays;
import java.util.Map;
public class DataReportBlock {
NamespaceID name;
Map<String, String[]> properties;
BlockState[] states;
BlockState defaultState;
/**
* Looks for the first state in {@link #states} with #isDefault set and stores it into {@link #defaultState}
*/
public void bindDefaultState() {
for(BlockState s : states) {
if(s.isDefault) {
defaultState = s;
return;
}
}
}
public static class BlockState {
protected Map<String, String> properties;
protected short id;
@SerializedName("default")
protected boolean isDefault;
@Override
public String toString() {
return "BlockState{" +
"properties=" + properties +
", id=" + id +
", isDefault=" + isDefault +
'}';
}
}
@Override
public String toString() {
return "blocks.DataReportBlock{" +
"name=" + name +
", properties=" + properties +
", states=" + Arrays.toString(states) +
", defaultState=" + defaultState +
'}';
}
}

View File

@ -1,42 +0,0 @@
package net.minestom.codegen.blocks;
public class PrismarineJSBlock {
int id;
String name;
double hardness;
boolean diggable;
boolean transparent;
int emitLight;
int filterLight;
String boundingBox;
int stackSize;
String material;
@Override
public String toString() {
return "blocks.PrismarineJSBlock{" +
"name='" + name + '\'' +
", id=" + id +
", hardness=" + hardness +
", diggable=" + diggable +
", transparent=" + transparent +
", emitLight=" + emitLight +
", filterLight=" + filterLight +
", boundingBox='" + boundingBox + '\'' +
", stackSize=" + stackSize +
", material='" + material + '\'' +
'}';
}
/*
TODO:
"harvestTools": {
"521": true,
"535": true,
"539": true,
"543": true,
"550": true
}
*/
}

View File

@ -1,66 +0,0 @@
package net.minestom.codegen.enchantment;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class EnchantmentEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(EnchantmentEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if(args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if(!targetFolder.exists()) {
targetFolder.mkdirs();
}
new EnchantmentEnumGenerator(targetFolder);
}
private EnchantmentEnumGenerator(File targetFolder) throws IOException {
super(targetFolder);
}
@Override
protected String getCategoryID() {
return "minecraft:enchantment";
}
@Override
public String getPackageName() {
return "net.minestom.server.item";
}
@Override
public String getClassName() {
return "Enchantment";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,8 +0,0 @@
package net.minestom.codegen.entitytypes;
public class BurgerEntity {
int id;
String name;
double width;
double height;
}

View File

@ -1,153 +0,0 @@
package net.minestom.codegen.entitytypes;
import com.google.common.base.CaseFormat;
import net.minestom.server.entity.EntitySpawnType;
import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.metadata.other.ExperienceOrbMeta;
import net.minestom.server.entity.metadata.other.PaintingMeta;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class EntityTypeContainer implements Comparable<EntityTypeContainer> {
private int id;
private NamespaceID name;
private double width;
private double height;
private Class<?> metaClass;
private EntitySpawnType spawnType;
public EntityTypeContainer(int id, NamespaceID name, double width, double height) {
this.id = id;
this.name = name;
this.width = width;
this.height = height;
String metaClassName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name.getPath());
// special cases
switch (metaClassName) {
case "Item":
metaClassName = "ItemEntity";
break;
case "Tnt":
metaClassName = "PrimedTnt";
break;
case "FishingBobber":
metaClassName = "FishingHook";
break;
case "Egg":
case "EnderPearl":
case "ExperienceBottle":
case "Potion":
case "Trident":
metaClassName = "Thrown" + metaClassName;
break;
default:
break;
}
metaClassName += "Meta";
this.metaClass = findClassIn("net.minestom.server.entity.metadata", metaClassName);
if (this.metaClass == PlayerMeta.class) {
this.spawnType = EntitySpawnType.PLAYER;
} else if (this.metaClass == PaintingMeta.class) {
this.spawnType = EntitySpawnType.PAINTING;
} else if (this.metaClass == ExperienceOrbMeta.class) {
this.spawnType = EntitySpawnType.EXPERIENCE_ORB;
} else if (LivingEntityMeta.class.isAssignableFrom(this.metaClass)) {
this.spawnType = EntitySpawnType.LIVING;
} else {
this.spawnType = EntitySpawnType.BASE;
}
}
public int getId() {
return id;
}
public NamespaceID getName() {
return name;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public Class<?> getMetaClass() {
return metaClass;
}
public EntitySpawnType getSpawnType() {
return spawnType;
}
@Override
public int compareTo(@NotNull EntityTypeContainer o) {
return Integer.compare(id, o.id);
}
private static Class<?> findClassIn(String pkg, String className) {
try {
return getClasses(pkg).stream()
.filter(clazz -> clazz.getSimpleName().equals(className))
.findAny()
.orElseThrow();
} catch (Throwable t) {
throw new IllegalStateException("Could not find class " + className + " in " + pkg, t);
}
}
private static List<Class<?>> getClasses(String packageName)
throws ClassNotFoundException, IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
List<Class<?>> classes = new ArrayList<>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes;
}
/**
* Recursive method used to find all classes in a given directory and subdirs.
*
* @param directory The base directory
* @param packageName The package name for classes found inside the base directory
* @return The classes
* @throws ClassNotFoundException
*/
private static List<Class<?>> findClasses(File directory, String packageName) throws ClassNotFoundException {
List<Class<?>> classes = new ArrayList<>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
}
}
return classes;
}
}

View File

@ -1,215 +0,0 @@
package net.minestom.codegen.entitytypes;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import net.minestom.codegen.ConstructorLambda;
import net.minestom.codegen.EnumGenerator;
import net.minestom.codegen.MinestomEnumGenerator;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntitySpawnType;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.registry.Registries;
import net.minestom.server.registry.ResourceGatherer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.*;
import java.util.function.BiFunction;
/**
* Generates an EntityType enum containing all data about entity types
*/
public class EntityTypeEnumGenerator extends MinestomEnumGenerator<EntityTypeContainer> {
private static final Logger LOGGER = LoggerFactory.getLogger(EntityTypeEnumGenerator.class);
private final String targetVersion;
private final File targetFolder;
public static void main(String[] args) throws IOException {
String targetVersion;
if (args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if (args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
new EntityTypeEnumGenerator(targetVersion, targetFolder);
}
private EntityTypeEnumGenerator(String targetVersion, File targetFolder) throws IOException {
this.targetVersion = targetVersion;
this.targetFolder = targetFolder;
generateTo(targetFolder);
}
/**
* Extract entity information from Burger (submodule of Minestom)
*
* @param gson
* @param url
* @return
* @throws IOException
*/
private List<BurgerEntity> parseEntitiesFromBurger(Gson gson, String url) throws IOException {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
LOGGER.debug("\tConnection established, reading file");
JsonObject dictionary = gson.fromJson(bufferedReader, JsonArray.class).get(0).getAsJsonObject();
JsonObject entitiesMap = dictionary.getAsJsonObject("entities").getAsJsonObject("entity");
List<BurgerEntity> entities = new LinkedList<>();
for (var entry : entitiesMap.entrySet()) {
BurgerEntity entity = gson.fromJson(entry.getValue(), BurgerEntity.class);
entities.add(entity);
}
return entities;
}
}
@Override
public String getPackageName() {
return "net.minestom.server.entity";
}
@Override
public String getClassName() {
return "EntityType";
}
@Override
protected Collection<EntityTypeContainer> compile() throws IOException {
Gson gson = new Gson();
LOGGER.debug("Loading PrismarineJS entity types data");
List<BurgerEntity> burgerEntities = parseEntitiesFromBurger(gson, BURGER_URL_BASE_URL + targetVersion + ".json");
TreeSet<EntityTypeContainer> types = new TreeSet<>(EntityTypeContainer::compareTo);
for (var burgerEntity : burgerEntities) {
if (burgerEntity.name.contains("~")) {
continue;
}
types.add(new EntityTypeContainer(
burgerEntity.id,
NamespaceID.from("minecraft:" + burgerEntity.name),
burgerEntity.width,
burgerEntity.height
));
}
return types;
}
@Override
protected void prepare(EnumGenerator generator) {
ClassName className = ClassName.get(getPackageName(), getClassName());
generator.addClassAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "{$S}", "deprecation").build());
generator.setParams(
ParameterSpec.builder(String.class, "namespaceID").addAnnotation(NotNull.class).build(),
ParameterSpec.builder(TypeName.DOUBLE, "width").build(),
ParameterSpec.builder(TypeName.DOUBLE, "height").build(),
ParameterSpec.builder(ParameterizedTypeName.get(
BiFunction.class,
Entity.class,
Metadata.class,
EntityMeta.class
), "metaConstructor").addAnnotation(NotNull.class).build(),
ParameterSpec.builder(EntitySpawnType.class, "spawnType").addAnnotation(NotNull.class).build()
);
generator.appendToConstructor(code -> {
code.addStatement("$T.$N.put($T.from(namespaceID), this)", Registries.class, "entityTypes", NamespaceID.class);
});
generator.addMethod("getId", new ParameterSpec[0], TypeName.SHORT, code -> {
code.addStatement("return (short) ordinal()");
});
generator.addMethod("getNamespaceID", new ParameterSpec[0], ClassName.get(String.class), code -> {
code.addStatement("return this.namespaceID");
});
generator.addMethod("getWidth", new ParameterSpec[0], TypeName.DOUBLE, code -> {
code.addStatement("return this.width");
});
generator.addMethod("getHeight", new ParameterSpec[0], TypeName.DOUBLE, code -> {
code.addStatement("return this.height");
});
generator.addMethod("getMetaConstructor", new ParameterSpec[0],
ParameterizedTypeName.get(
BiFunction.class,
Entity.class,
Metadata.class,
EntityMeta.class
),
code -> code.addStatement("return this.metaConstructor")
);
generator.addMethod("getSpawnType", new ParameterSpec[0], ClassName.get(EntitySpawnType.class), code -> {
code.addStatement("return this.spawnType");
});
generator.addStaticField(ArrayTypeName.of(ClassName.get(EntityType.class)), "VALUES", "values()");
generator.addStaticMethod("fromId", new ParameterSpec[]{ParameterSpec.builder(TypeName.SHORT, "id").build()}, className, code -> {
code.beginControlFlow("if(id >= 0 && id < VALUES.length)")
.addStatement("return VALUES[id]")
.endControlFlow()
.addStatement("return null");
});
// implement Keyed
generator.addSuperinterface(ClassName.get(Keyed.class));
generator.addField(ClassName.get(Key.class), "key", true);
generator.appendToConstructor(code -> code.addStatement("this.key = Key.key(this.namespaceID)"));
generator.addMethod("key", new ParameterSpec[0], ClassName.get(Key.class), code -> code.addStatement("return this.key"));
}
@Override
protected void writeSingle(EnumGenerator generator, EntityTypeContainer type) {
String instanceName = type.getName().getPath().toUpperCase();
generator.addInstance(instanceName,
"\"" + type.getName().toString() + "\"",
type.getWidth(),
type.getHeight(),
new ConstructorLambda(ClassName.get(type.getMetaClass())),
"EntitySpawnType." + type.getSpawnType().name()
);
}
@Override
protected List<JavaFile> postGeneration(Collection<EntityTypeContainer> types) {
return Collections.emptyList();
}
@Override
protected void postWrite(EnumGenerator generator) {
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,66 +0,0 @@
package net.minestom.codegen.fluids;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class FluidEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(FluidEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if(args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if(!targetFolder.exists()) {
targetFolder.mkdirs();
}
new FluidEnumGenerator(targetFolder);
}
private FluidEnumGenerator(File targetFolder) throws IOException {
super(targetFolder);
}
@Override
protected String getCategoryID() {
return "minecraft:fluid";
}
@Override
public String getPackageName() {
return "net.minestom.server.fluids";
}
@Override
public String getClassName() {
return "Fluid";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,7 +0,0 @@
package net.minestom.codegen.items;
public class BurgerItem {
int numeric_id;
String text_id;
int max_stack_size;
}

View File

@ -1,8 +0,0 @@
package net.minestom.codegen.items;
import net.minestom.server.utils.NamespaceID;
public class DataReportItem {
NamespaceID name;
}

View File

@ -1,39 +0,0 @@
package net.minestom.codegen.items;
import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.NamespaceID;
public class ItemContainer implements Comparable<ItemContainer> {
private int id;
private NamespaceID name;
private int stackSize;
private Block block;
public ItemContainer(int id, NamespaceID name, int stackSize, Block block) {
this.id = id;
this.name = name;
this.stackSize = stackSize;
this.block = block;
}
public int getId() {
return id;
}
public NamespaceID getName() {
return name;
}
public Block getBlock() {
return block;
}
public int getStackSize() {
return stackSize;
}
@Override
public int compareTo(ItemContainer o) {
return Integer.compare(id, o.id);
}
}

View File

@ -1,254 +0,0 @@
package net.minestom.codegen.items;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import net.minestom.codegen.EnumGenerator;
import net.minestom.codegen.MinestomEnumGenerator;
import net.minestom.codegen.PrismarinePaths;
import net.minestom.server.instance.block.Block;
import net.minestom.server.registry.Registries;
import net.minestom.server.registry.ResourceGatherer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.URL;
import java.util.*;
/**
* Generates a Material enum containing all data about items
* <p>
* Assumes that Block is available
*/
public class ItemEnumGenerator extends MinestomEnumGenerator<ItemContainer> {
private static final Logger LOGGER = LoggerFactory.getLogger(ItemEnumGenerator.class);
private final String targetVersion;
private final File targetFolder;
public static void main(String[] args) throws IOException {
String targetVersion;
if (args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if (args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
new ItemEnumGenerator(targetVersion, targetFolder);
}
private ItemEnumGenerator(String targetVersion, File targetFolder) throws IOException {
this.targetVersion = targetVersion;
this.targetFolder = targetFolder;
generateTo(targetFolder);
}
/**
* Extract item information from Burger (submodule of Minestom)
*
* @param gson
* @param url
* @return
* @throws IOException
*/
private List<BurgerItem> parseItemsFromBurger(Gson gson, String url) throws IOException {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
LOGGER.debug("\tConnection established, reading file");
JsonObject dictionary = gson.fromJson(bufferedReader, JsonArray.class).get(0).getAsJsonObject();
JsonObject itemMap = dictionary.getAsJsonObject("items").getAsJsonObject("item");
List<BurgerItem> items = new LinkedList<>();
for (var entry : itemMap.entrySet()) {
BurgerItem item = gson.fromJson(entry.getValue(), BurgerItem.class);
items.add(item);
}
return items;
}
}
@Override
public String getPackageName() {
return "net.minestom.server.item";
}
@Override
public String getClassName() {
return "Material";
}
@Override
protected Collection<ItemContainer> compile() throws IOException {
Gson gson = new Gson();
LOGGER.debug("Finding path for PrismarineJS items");
JsonObject dataPaths = gson.fromJson(new BufferedReader(new FileReader(PRISMARINE_JS_DATA_PATHS)), JsonObject.class);
JsonObject pathsJson = dataPaths.getAsJsonObject("pc").getAsJsonObject(targetVersion);
PrismarinePaths paths = gson.fromJson(pathsJson, PrismarinePaths.class);
LOGGER.debug("Loading PrismarineJS blocks data");
List<BurgerItem> burgerItems = parseItemsFromBurger(gson, BURGER_URL_BASE_URL + targetVersion + ".json");
TreeSet<ItemContainer> items = new TreeSet<>(ItemContainer::compareTo);
for (var burgerItem : burgerItems) {
items.add(new ItemContainer(burgerItem.numeric_id, NamespaceID.from("minecraft:" + burgerItem.text_id), burgerItem.max_stack_size, getBlock(burgerItem.text_id.toUpperCase())));
}
return items;
}
/**
* Returns a block with the given name. Returns null if none
*
* @param itemName
* @return
*/
private Block getBlock(String itemName) {
// special cases
if (itemName.equals("REDSTONE"))
return Block.REDSTONE_WIRE;
// end of special cases
try {
return Block.valueOf(itemName);
} catch (IllegalArgumentException e) {
return null;
}
}
@Override
protected void prepare(EnumGenerator generator) {
ClassName className = ClassName.get(getPackageName(), getClassName());
generator.addClassAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "{$S}", "deprecation").build());
generator.setParams(ParameterSpec.builder(String.class, "namespaceID").addAnnotation(NotNull.class).build(), ParameterSpec.builder(TypeName.INT, "maxDefaultStackSize").build(),
ParameterSpec.builder(Block.class, "correspondingBlock").addAnnotation(Nullable.class).build());
generator.appendToConstructor(code -> {
code.addStatement("$T.$N.put($T.from(namespaceID), this)", Registries.class, "materials", NamespaceID.class);
});
generator.addMethod("getId", new ParameterSpec[0], TypeName.SHORT, code -> { code.addStatement("return (short)ordinal()");});
generator.addMethod("getName", new ParameterSpec[0], ClassName.get(String.class), code -> { code.addStatement("return namespaceID");});
generator.addMethod("getMaxDefaultStackSize", new ParameterSpec[0], TypeName.INT, code -> { code.addStatement("return maxDefaultStackSize");});
generator.addMethod("isBlock", new ParameterSpec[0], TypeName.BOOLEAN, code -> { code.addStatement("return correspondingBlock != null && this != AIR");});
generator.addMethod("getBlock", new ParameterSpec[0], ClassName.get(Block.class), code -> { code.addStatement("return correspondingBlock");});
generator.addStaticMethod("fromId", new ParameterSpec[]{ParameterSpec.builder(TypeName.SHORT, "id").build()}, className, code -> {
code.beginControlFlow("if(id >= 0 && id < values().length)")
.addStatement("return values()[id]")
.endControlFlow()
.addStatement("return AIR");
});
// hard coded methods
generator.addMethod("isHelmet", new ParameterSpec[0], TypeName.BOOLEAN, code -> { code.addStatement("return toString().endsWith(\"HELMET\")");});
generator.addMethod("isChestplate", new ParameterSpec[0], TypeName.BOOLEAN, code -> { code.addStatement("return toString().endsWith(\"CHESTPLATE\")");});
generator.addMethod("isLeggings", new ParameterSpec[0], TypeName.BOOLEAN, code -> { code.addStatement("return toString().endsWith(\"LEGGINGS\")");});
generator.addMethod("isBoots", new ParameterSpec[0], TypeName.BOOLEAN, code -> { code.addStatement("return toString().endsWith(\"BOOTS\")");});
generator.addMethod("isArmor", new ParameterSpec[0], TypeName.BOOLEAN, code -> { code.addStatement("return isChestplate() || isHelmet() || isLeggings() || isBoots()");});
generator.addMethod("isFood", new ParameterSpec[0], TypeName.BOOLEAN, code -> {
code.beginControlFlow("switch(this)")
.add("case APPLE:\n")
.add("case MUSHROOM_STEW:\n")
.add("case BREAD:\n")
.add("case PORKCHOP:\n")
.add("case COOKED_PORKCHOP:\n")
.add("case GOLDEN_APPLE:\n")
.add("case ENCHANTED_GOLDEN_APPLE:\n")
.add("case COD:\n")
.add("case SALMON:\n")
.add("case TROPICAL_FISH:\n")
.add("case PUFFERFISH:\n")
.add("case COOKED_COD:\n")
.add("case COOKED_SALMON:\n")
.add("case CAKE:\n")
.add("case COOKIE:\n")
.add("case MELON_SLICE:\n")
.add("case DRIED_KELP:\n")
.add("case BEEF:\n")
.add("case COOKED_BEEF:\n")
.add("case CHICKEN:\n")
.add("case COOKED_CHICKEN:\n")
.add("case ROTTEN_FLESH:\n")
.add("case SPIDER_EYE:\n")
.add("case CARROT:\n")
.add("case POTATO:\n")
.add("case BAKED_POTATO:\n")
.add("case POISONOUS_POTATO:\n")
.add("case PUMPKIN_PIE:\n")
.add("case RABBIT:\n")
.add("case COOKED_RABBIT:\n")
.add("case RABBIT_STEW:\n")
.add("case MUTTON:\n")
.add("case COOKED_MUTTON:\n")
.add("case BEETROOT:\n")
.add("case BEETROOT_SOUP:\n")
.add("case SWEET_BERRIES:\n")
.add("case HONEY_BOTTLE:\n")
.add("case CHORUS_FRUIT:\n")
.addStatement("return true")
.endControlFlow()
.addStatement("return false");
});
generator.addMethod("hasState", new ParameterSpec[0], TypeName.BOOLEAN, code -> {
code.beginControlFlow("switch(this)")
.add("case BOW:\n")
.add("case TRIDENT:\n")
.add("case CROSSBOW:\n")
.add("case SHIELD:\n")
.addStatement("return true")
.endControlFlow()
.addStatement("return isFood()");
});
// implement Keyed
generator.addSuperinterface(ClassName.get(Keyed.class));
generator.addField(ClassName.get(Key.class), "key", true);
generator.appendToConstructor(code -> code.addStatement("this.key = Key.key(this.namespaceID)"));
generator.addMethod("key", new ParameterSpec[0], ClassName.get(Key.class), code -> code.addStatement("return this.key"));
}
@Override
protected void writeSingle(EnumGenerator generator, ItemContainer item) {
String instanceName = item.getName().getPath().toUpperCase();
generator.addInstance(instanceName,
"\"" + item.getName().toString() + "\"",
item.getStackSize(),
item.getBlock() == null ? "null" : ("Block." + item.getBlock().name())
);
}
@Override
protected List<JavaFile> postGeneration(Collection<ItemContainer> items) throws IOException {
return Collections.emptyList();
}
@Override
protected void postWrite(EnumGenerator generator) {
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,66 +0,0 @@
package net.minestom.codegen.particles;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class ParticleEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(ParticleEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if(args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if(!targetFolder.exists()) {
targetFolder.mkdirs();
}
new ParticleEnumGenerator(targetFolder);
}
private ParticleEnumGenerator(File targetFolder) throws IOException {
super(targetFolder);
}
@Override
protected String getCategoryID() {
return "minecraft:particle_type";
}
@Override
public String getPackageName() {
return "net.minestom.server.particle";
}
@Override
public String getClassName() {
return "Particle";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,66 +0,0 @@
package net.minestom.codegen.potions;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class PotionEffectEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(PotionEffectEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if (args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if (args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
new PotionEffectEnumGenerator(targetFolder);
}
private PotionEffectEnumGenerator(File targetFolder) throws IOException {
super(targetFolder, true, true);
}
@Override
protected String getCategoryID() {
return "minecraft:mob_effect";
}
@Override
public String getPackageName() {
return "net.minestom.server.potion";
}
@Override
public String getClassName() {
return "PotionEffect";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,66 +0,0 @@
package net.minestom.codegen.potions;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class PotionEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(PotionEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if (args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if (args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
new PotionEnumGenerator(targetFolder);
}
private PotionEnumGenerator(File targetFolder) throws IOException {
super(targetFolder);
}
@Override
protected String getCategoryID() {
return "minecraft:potion";
}
@Override
public String getPackageName() {
return "net.minestom.server.potion";
}
@Override
public String getClassName() {
return "PotionType";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,77 +0,0 @@
package net.minestom.codegen.sounds;
import com.squareup.javapoet.ClassName;
import net.kyori.adventure.sound.Sound;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.EnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class SoundEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(SoundEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if(args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if(!targetFolder.exists()) {
targetFolder.mkdirs();
}
new SoundEnumGenerator(targetFolder);
}
private SoundEnumGenerator(File targetFolder) throws IOException {
super(targetFolder);
}
@Override
protected void prepare(EnumGenerator generator) {
super.prepare(generator);
// implement type as well
generator.addSuperinterface(ClassName.get(Sound.Type.class));
}
@Override
protected String getCategoryID() {
return "minecraft:sound_event";
}
@Override
public String getPackageName() {
return "net.minestom.server.sound";
}
@Override
public String getClassName() {
return "SoundEvent";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,66 +0,0 @@
package net.minestom.codegen.stats;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class BiomesEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(BiomesEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if(args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if(!targetFolder.exists()) {
targetFolder.mkdirs();
}
new BiomesEnumGenerator(targetFolder);
}
private BiomesEnumGenerator(File targetFolder) throws IOException {
super(targetFolder, false);
}
@Override
protected String getCategoryID() {
return "minecraft:biome";
}
@Override
public String getPackageName() {
return "net.minestom.server.instance";
}
@Override
public String getClassName() {
return "Biome";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -1,66 +0,0 @@
package net.minestom.codegen.stats;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
public class StatsEnumGenerator extends BasicEnumGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(StatsEnumGenerator.class);
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
targetVersion = args[0];
try {
ResourceGatherer.ensureResourcesArePresent(targetVersion); // TODO
} catch (IOException e) {
e.printStackTrace();
}
String targetPart = DEFAULT_TARGET_PATH;
if(args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if(!targetFolder.exists()) {
targetFolder.mkdirs();
}
new StatsEnumGenerator(targetFolder);
}
private StatsEnumGenerator(File targetFolder) throws IOException {
super(targetFolder);
}
@Override
protected String getCategoryID() {
return "minecraft:custom_stat";
}
@Override
public String getPackageName() {
return "net.minestom.server.stat";
}
@Override
public String getClassName() {
return "StatisticType";
}
@Override
public Logger getLogger() {
return LOGGER;
}
}

View File

@ -12,7 +12,7 @@ import net.minestom.server.event.GlobalEventHandler;
import net.minestom.server.exception.ExceptionManager;
import net.minestom.server.extensions.Extension;
import net.minestom.server.extensions.ExtensionManager;
import net.minestom.server.fluids.Fluid;
import net.minestom.server.fluid.Fluid;
import net.minestom.server.gamedata.loottables.LootTableManager;
import net.minestom.server.gamedata.tags.TagManager;
import net.minestom.server.instance.Chunk;
@ -39,7 +39,7 @@ import net.minestom.server.recipe.RecipeManager;
import net.minestom.server.registry.ResourceGatherer;
import net.minestom.server.scoreboard.TeamManager;
import net.minestom.server.sound.SoundEvent;
import net.minestom.server.stat.StatisticType;
import net.minestom.server.statistic.StatisticType;
import net.minestom.server.storage.StorageLocation;
import net.minestom.server.storage.StorageManager;
import net.minestom.server.terminal.MinestomTerminal;

View File

@ -26,7 +26,7 @@ public class DamageType implements DataContainer {
public static final DamageType ON_FIRE = new DamageType("attack.onFire") {
@Override
protected SoundEvent getPlayerSound(@NotNull Player player) {
return SoundEvent.ENTITY_PLAYER_HURT_ON_FIRE;
return SoundEvent.PLAYER_HURT_ON_FIRE;
}
};
private final String identifier;
@ -143,11 +143,11 @@ public class DamageType implements DataContainer {
}
protected SoundEvent getGenericSound(@NotNull LivingEntity entity) {
return SoundEvent.ENTITY_GENERIC_HURT;
return SoundEvent.GENERIC_HURT;
}
protected SoundEvent getPlayerSound(@NotNull Player player) {
return SoundEvent.ENTITY_PLAYER_HURT;
return SoundEvent.PLAYER_HURT;
}
@Override

View File

@ -52,7 +52,7 @@ public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider<Pot
public Builder potionType(@NotNull PotionType potionType) {
this.potionType = potionType;
this.nbt.setString("Potion", potionType.getNamespaceID());
this.nbt.setString("Potion", potionType.getNamespaceID().asString());
return this;
}

View File

@ -210,7 +210,7 @@ public class PlayerDiggingListener {
}
/**
* Adds the effect {@link PotionEffect#MINING_FATIGUE} to the player.
* Adds the effect {@link PotionEffect#DIG_SLOWDOWN} to the player.
* <p>
* Used for {@link CustomBlock} break delay or when the {@link PlayerStartDiggingEvent} is cancelled
* to remove the player break animation.
@ -223,7 +223,7 @@ public class PlayerDiggingListener {
EntityEffectPacket entityEffectPacket = new EntityEffectPacket();
entityEffectPacket.entityId = player.getEntityId();
entityEffectPacket.potion = new Potion(
PotionEffect.MINING_FATIGUE,
PotionEffect.DIG_SLOWDOWN,
(byte) -1,
0,
false,
@ -246,7 +246,7 @@ public class PlayerDiggingListener {
RemoveEntityEffectPacket removeEntityEffectPacket = new RemoveEntityEffectPacket();
removeEntityEffectPacket.entityId = player.getEntityId();
removeEntityEffectPacket.effect = PotionEffect.MINING_FATIGUE;
removeEntityEffectPacket.effect = PotionEffect.DIG_SLOWDOWN;
player.getPlayerConnection().sendPacket(removeEntityEffectPacket);
}
}

View File

@ -2,7 +2,7 @@ package net.minestom.server.network.packet.server.play;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.EntityType;
import net.minestom.server.fluids.Fluid;
import net.minestom.server.fluid.Fluid;
import net.minestom.server.gamedata.tags.Tag;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Material;
@ -50,7 +50,7 @@ public class TagsPacket implements ServerPacket {
public void read(@NotNull BinaryReader reader) {
readTags(reader, blockTags, id -> NamespaceID.from("minecraft", Block.values()[id].getName()));
readTags(reader, itemTags, id -> NamespaceID.from("minecraft", Material.values()[id].getName()));
readTags(reader, fluidTags, id -> NamespaceID.from(Fluid.values()[id].getNamespaceID()));
readTags(reader, fluidTags, id -> Fluid.fromId(id.shortValue()).getNamespaceID());
readTags(reader, entityTags, id -> NamespaceID.from(EntityType.values()[id].getNamespaceID()));
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.stat;
import net.minestom.server.entity.Player;
import net.minestom.server.statistic.StatisticType;
import org.jetbrains.annotations.NotNull;
/**