Merge branch 'master' into tab-complete-fix

# Conflicts:
#	src/test/java/net/minestom/server/command/CommandSuggestionIntegrationTest.java
This commit is contained in:
steank 2024-12-03 13:13:34 -08:00
commit 6b658456f3
No known key found for this signature in database
GPG Key ID: 5560C0853834EF8A
809 changed files with 16157 additions and 15476 deletions

View File

@ -23,6 +23,7 @@ allprojects {
description = shortDescription
repositories {
mavenLocal()
mavenCentral()
}
@ -72,7 +73,6 @@ dependencies {
implementation(libs.minestomData)
// Performance/data structures
implementation(libs.caffeine)
api(libs.fastutil)
implementation(libs.bundles.flare)
api(libs.gson)
@ -116,7 +116,7 @@ tasks {
replaceToken("\"&ARTIFACT\"", if (artifact == null) "null" else "\"${artifact}\"", gitFile)
}
nexusPublishing{
nexusPublishing {
useStaging.set(true)
this.packageGroup.set("net.minestom")

View File

@ -4,6 +4,7 @@ import net.minestom.codegen.color.DyeColorGenerator;
import net.minestom.codegen.fluid.FluidGenerator;
import net.minestom.codegen.particle.ParticleGenerator;
import net.minestom.codegen.recipe.RecipeTypeGenerator;
import net.minestom.codegen.util.GenericEnumGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,9 +23,21 @@ public class Generators {
// Special generators
new DyeColorGenerator(resource("dye_colors.json"), outputFolder).generate();
new RecipeTypeGenerator(resource("recipe_types.json"), outputFolder).generate();
new ParticleGenerator(resource("particles.json"), outputFolder).generate();
new ConstantsGenerator(resource("constants.json"), outputFolder).generate();
new RecipeTypeGenerator(resource("recipe_types.json"), outputFolder).generate();
new GenericEnumGenerator("net.minestom.server.recipe.display", "RecipeDisplayType",
resource("recipe_display_types.json"), outputFolder).generate();
new GenericEnumGenerator("net.minestom.server.recipe.display", "SlotDisplayType",
resource("slot_display_types.json"), outputFolder).generate();
new GenericEnumGenerator("net.minestom.server.recipe", "RecipeBookCategory",
resource("recipe_book_categories.json"), outputFolder).generate();
new GenericEnumGenerator("net.minestom.server.item.component", "ConsumeEffectType",
resource("consume_effects.json"), outputFolder).packagePrivate().generate();
new GenericEnumGenerator("net.minestom.server.command", "ArgumentParserType",
resource("command_arguments.json"), outputFolder).generate();
new GenericEnumGenerator("net.minestom.server.entity", "VillagerType",
resource("villager_types.json"), outputFolder).generate();
var generator = new CodeGenerator(outputFolder);
@ -38,6 +51,8 @@ public class Generators {
generator.generate(resource("custom_statistics.json"), "net.minestom.server.statistic", "StatisticType", "StatisticTypeImpl", "StatisticTypes");
generator.generate(resource("attributes.json"), "net.minestom.server.entity.attribute", "Attribute", "AttributeImpl", "Attributes");
generator.generate(resource("feature_flags.json"), "net.minestom.server", "FeatureFlag", "FeatureFlagImpl", "FeatureFlags");
generator.generate(resource("villager_professions.json"), "net.minestom.server.entity", "VillagerProfession", "VillagerProfessionImpl", "VillagerProfessions");
// Dynamic registries
generator.generateKeys(resource("chat_types.json"), "net.minestom.server.message", "ChatType", "ChatTypes");
@ -54,17 +69,7 @@ public class Generators {
// Generate fluids
new FluidGenerator(resource("fluids.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();
LOGGER.info("Finished generating code");
}

View File

@ -29,6 +29,8 @@ public abstract class MinestomCodeGenerator {
}
protected static String toConstant(String namespace) {
return namespace.replace("minecraft:", "").toUpperCase(Locale.ROOT);
return namespace.replace("minecraft:", "")
.replace("brigadier:", "")
.toUpperCase(Locale.ROOT);
}
}

View File

@ -1,212 +0,0 @@
package net.minestom.codegen.entity;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
public final class VillagerProfessionGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(VillagerProfessionGenerator.class);
private final InputStream villagerProfessionsFile;
private final File outputFolder;
public VillagerProfessionGenerator(@Nullable InputStream villagerProfessionsFile, @NotNull File outputFolder) {
this.villagerProfessionsFile = villagerProfessionsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (villagerProfessionsFile == null) {
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 = GSON.fromJson(new InputStreamReader(villagerProfessionsFile), JsonArray.class);
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(
List.of(
JavaFile.builder("net.minestom.server.entity.metadata.villager", villagerProfessionClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -1,164 +0,0 @@
package net.minestom.codegen.entity;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
public final class VillagerTypeGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(VillagerTypeGenerator.class);
private final InputStream villagerTypesFile;
private final File outputFolder;
public VillagerTypeGenerator(@Nullable InputStream villagerTypesFile, @NotNull File outputFolder) {
this.villagerTypesFile = villagerTypesFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (villagerTypesFile == null) {
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 = GSON.fromJson(new InputStreamReader(villagerTypesFile), JsonArray.class);
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(
List.of(
JavaFile.builder("net.minestom.server.entity.metadata.villager", villagerTypeClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}

View File

@ -1,113 +1,21 @@
package net.minestom.codegen.recipe;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import net.minestom.codegen.util.GenericEnumGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.List;
import java.util.stream.StreamSupport;
public class RecipeTypeGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(RecipeTypeGenerator.class);
private final InputStream recipeTypesFile;
private final File outputFolder;
public class RecipeTypeGenerator extends GenericEnumGenerator {
public RecipeTypeGenerator(@Nullable InputStream recipeTypesFile, @NotNull File outputFolder) {
this.recipeTypesFile = recipeTypesFile;
this.outputFolder = outputFolder;
super("net.minestom.server.recipe", "RecipeType", recipeTypesFile, outputFolder);
}
@Override
public void generate() {
if (recipeTypesFile == null) {
LOGGER.error("Failed to find recipe_types.json.");
LOGGER.error("Stopped code generation for recipe 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
JsonArray recipeTypes = GSON.fromJson(new InputStreamReader(recipeTypesFile), JsonArray.class);
ClassName recipeTypeCN = ClassName.get("net.minestom.server.recipe", "RecipeType");
TypeSpec.Builder recipeTypeEnum = TypeSpec.enumBuilder(recipeTypeCN)
.addSuperinterface(ClassName.get("net.minestom.server.registry", "StaticProtocolObject"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
ClassName namespaceIdCN = ClassName.get("net.minestom.server.utils", "NamespaceID");
ClassName networkBufferCN = ClassName.get("net.minestom.server.network", "NetworkBuffer");
ParameterizedTypeName networkBufferTypeCN = ParameterizedTypeName.get(networkBufferCN.nestedClass("Type"), recipeTypeCN);
// Fields
recipeTypeEnum.addFields(
List.of(
FieldSpec.builder(networkBufferTypeCN, "NETWORK_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$T.Enum($T.class)", networkBufferCN, recipeTypeCN)
.build(),
FieldSpec.builder(namespaceIdCN, "namespace", Modifier.PRIVATE, Modifier.FINAL).build()
)
);
// Methods
recipeTypeEnum.addMethods(
List.of(
// Constructor
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIdCN, "namespace").addAnnotation(NotNull.class).build())
.addStatement("this.namespace = namespace")
.build(),
MethodSpec.methodBuilder("namespace")
.addModifiers(Modifier.PUBLIC)
.addAnnotation(NotNull.class)
.addAnnotation(Override.class)
.returns(namespaceIdCN)
.addStatement("return this.namespace")
.build(),
MethodSpec.methodBuilder("id")
.addModifiers(Modifier.PUBLIC)
.returns(TypeName.INT)
.addAnnotation(Override.class)
.addStatement("return this.ordinal()")
.build()
)
);
// Use data
for (JsonObject recipeTypeObject : StreamSupport.stream(recipeTypes.spliterator(), true).map(JsonElement::getAsJsonObject).sorted(Comparator.comparingInt(o -> o.get("id").getAsInt())).toList()) {
String recipeTypeName = recipeTypeObject.get("name").getAsString();
recipeTypeEnum.addEnumConstant(recipeTypeConstantName(recipeTypeName), TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIdCN, recipeTypeName
).build()
);
}
// Write files to outputFolder
writeFiles(
List.of(
JavaFile.builder("net.minestom.server.recipe", recipeTypeEnum.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
protected @NotNull String nameGenerator(@NotNull String namespaceId) {
return toConstant(namespaceId).replace("CRAFTING_", "");
}
private static @NotNull String recipeTypeConstantName(@NotNull String name) {
return toConstant(name).replace("CRAFTING_", "");
}
}

View File

@ -0,0 +1,135 @@
package net.minestom.codegen.util;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.List;
import java.util.stream.StreamSupport;
public class GenericEnumGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(GenericEnumGenerator.class);
private final String packageName;
private final String className;
private final InputStream entriesFile;
private final File outputFolder;
private boolean isPackagePrivate = false;
public GenericEnumGenerator(
@NotNull String packageName, @NotNull String className,
@Nullable InputStream entriesFile, @NotNull File outputFolder
) {
this.packageName = packageName;
this.className = className;
this.entriesFile = entriesFile;
this.outputFolder = outputFolder;
}
public GenericEnumGenerator packagePrivate() {
this.isPackagePrivate = true;
return this;
}
@Override
public void generate() {
if (entriesFile == null) {
LOGGER.error("Failed to find entries file.");
LOGGER.error("Stopped code generation for {}.", className);
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
JsonArray entryList = GSON.fromJson(new InputStreamReader(entriesFile), JsonArray.class);
ClassName entryCN = ClassName.get(packageName, className);
Modifier[] modifiers = isPackagePrivate ? new Modifier[0] : new Modifier[]{Modifier.PUBLIC};
TypeSpec.Builder entryEnum = TypeSpec.enumBuilder(entryCN)
.addSuperinterface(ClassName.get("net.minestom.server.registry", "StaticProtocolObject"))
.addModifiers(modifiers).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
ClassName namespaceIdCN = ClassName.get("net.minestom.server.utils", "NamespaceID");
ClassName networkBufferCN = ClassName.get("net.minestom.server.network", "NetworkBuffer");
ParameterizedTypeName networkBufferTypeCN = ParameterizedTypeName.get(networkBufferCN.nestedClass("Type"), entryCN);
ClassName binaryTagSerializerRawCN = ClassName.get("net.minestom.server.utils.nbt", "BinaryTagSerializer");
ParameterizedTypeName binaryTagSerializerCN = ParameterizedTypeName.get(binaryTagSerializerRawCN, entryCN);
// Fields
entryEnum.addFields(
List.of(
FieldSpec.builder(networkBufferTypeCN, "NETWORK_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$T.Enum($T.class)", networkBufferCN, entryCN)
.build(),
FieldSpec.builder(binaryTagSerializerCN, "NBT_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$T.fromEnumKeyed($T.class)", binaryTagSerializerRawCN, entryCN)
.build(),
FieldSpec.builder(namespaceIdCN, "namespace", Modifier.PRIVATE, Modifier.FINAL).build()
)
);
// Methods
entryEnum.addMethods(
List.of(
// Constructor
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIdCN, "namespace").addAnnotation(NotNull.class).build())
.addStatement("this.namespace = namespace")
.build(),
MethodSpec.methodBuilder("namespace")
.addModifiers(Modifier.PUBLIC)
.addAnnotation(NotNull.class)
.addAnnotation(Override.class)
.returns(namespaceIdCN)
.addStatement("return this.namespace")
.build(),
MethodSpec.methodBuilder("id")
.addModifiers(Modifier.PUBLIC)
.returns(TypeName.INT)
.addAnnotation(Override.class)
.addStatement("return this.ordinal()")
.build()
)
);
// Use data
for (JsonObject entryObject : StreamSupport.stream(entryList.spliterator(), true).map(JsonElement::getAsJsonObject).sorted(Comparator.comparingInt(o -> o.get("id").getAsInt())).toList()) {
String entryName = entryObject.get("name").getAsString();
entryEnum.addEnumConstant(nameGenerator(entryName), TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIdCN, entryName
).build()
);
}
// Write files to outputFolder
writeFiles(
List.of(
JavaFile.builder(packageName, entryEnum.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
protected @NotNull String nameGenerator(@NotNull String namespaceId) {
return toConstant(namespaceId);
}
}

View File

@ -8,9 +8,9 @@ import net.kyori.adventure.text.format.TextDecoration;
import net.minestom.demo.block.TestBlockHandler;
import net.minestom.demo.block.placement.DripstonePlacementRule;
import net.minestom.demo.commands.*;
import net.minestom.demo.recipe.ShapelessRecipe;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandManager;
import net.minestom.server.entity.Player;
import net.minestom.server.event.server.ServerListPingEvent;
import net.minestom.server.extras.MojangAuth;
import net.minestom.server.extras.lan.OpenToLAN;
@ -19,14 +19,10 @@ import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.server.play.DeclareRecipesPacket;
import net.minestom.server.ping.ResponseData;
import net.minestom.server.recipe.RecipeCategory;
import net.minestom.server.recipe.ShapedRecipe;
import net.minestom.server.recipe.ShapelessRecipe;
import net.minestom.server.recipe.RecipeBookCategory;
import net.minestom.server.utils.identity.NamedAndIdentified;
import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.util.List;
@ -81,6 +77,8 @@ public class Main {
commandManager.register(new PotionCommand());
commandManager.register(new CookieCommand());
commandManager.register(new WorldBorderCommand());
commandManager.register(new TestInstabreakCommand());
commandManager.register(new AttributeCommand());
commandManager.setUnknownCommandCallback((sender, command) -> sender.sendMessage(Component.text("Unknown command", NamedTextColor.RED)));
@ -122,37 +120,13 @@ public class Main {
//responseData.setPlayersHidden(true);
});
var ironBlockRecipe = new ShapedRecipe(
"minestom:test", 2, 2, "",
RecipeCategory.Crafting.MISC,
List.of(
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.IRON_INGOT))),
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.IRON_INGOT))),
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.IRON_INGOT))),
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.IRON_INGOT)))
), ItemStack.of(Material.IRON_BLOCK), true) {
@Override
public boolean shouldShow(@NotNull Player player) {
return true;
}
};
MinecraftServer.getRecipeManager().addRecipe(ironBlockRecipe);
var recipe = new ShapelessRecipe(
"minestom:test2", "abc",
RecipeCategory.Crafting.MISC,
List.of(
new DeclareRecipesPacket.Ingredient(List.of(ItemStack.of(Material.DIRT)))
),
MinecraftServer.getRecipeManager().addRecipe(new ShapelessRecipe(
RecipeBookCategory.CRAFTING_MISC,
List.of(Material.DIRT),
ItemStack.builder(Material.GOLD_BLOCK)
.set(ItemComponent.CUSTOM_NAME, Component.text("abc"))
.build()
) {
@Override
public boolean shouldShow(@NotNull Player player) {
return true;
}
};
MinecraftServer.getRecipeManager().addRecipe(recipe);
));
new PlayerInit().init();

View File

@ -5,20 +5,17 @@ import net.kyori.adventure.text.Component;
import net.minestom.server.FeatureFlag;
import net.minestom.server.MinecraftServer;
import net.minestom.server.advancements.FrameType;
import net.minestom.server.advancements.notifications.Notification;
import net.minestom.server.advancements.notifications.NotificationCenter;
import net.minestom.server.advancements.Notification;
import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.adventure.audience.Audiences;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.*;
import net.minestom.server.entity.damage.Damage;
import net.minestom.server.entity.metadata.projectile.FireworkRocketMeta;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventNode;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.item.ItemDropEvent;
import net.minestom.server.event.item.PickupItemEvent;
import net.minestom.server.event.item.*;
import net.minestom.server.event.player.*;
import net.minestom.server.event.server.ServerTickMonitorEvent;
import net.minestom.server.instance.Instance;
@ -30,25 +27,23 @@ import net.minestom.server.instance.block.predicate.BlockPredicate;
import net.minestom.server.instance.block.predicate.BlockTypeFilter;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemAnimation;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.component.BlockPredicates;
import net.minestom.server.item.component.EnchantmentList;
import net.minestom.server.item.component.LodestoneTracker;
import net.minestom.server.item.component.PotionContents;
import net.minestom.server.item.enchant.Enchantment;
import net.minestom.server.item.component.Consumable;
import net.minestom.server.monitoring.BenchmarkManager;
import net.minestom.server.monitoring.TickMonitor;
import net.minestom.server.network.packet.server.common.CustomReportDetailsPacket;
import net.minestom.server.network.packet.server.common.ServerLinksPacket;
import net.minestom.server.potion.CustomPotionEffect;
import net.minestom.server.potion.PotionEffect;
import net.minestom.server.sound.SoundEvent;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.time.TimeUnit;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
@ -94,20 +89,13 @@ public class PlayerInit {
itemEntity.setInstance(player.getInstance(), playerPos.withY(y -> y + 1.5));
Vec velocity = playerPos.direction().mul(6);
itemEntity.setVelocity(velocity);
var firework = new Entity(EntityType.FIREWORK_ROCKET);
firework.setInstance(player.getInstance());
var meta = (FireworkRocketMeta) firework.getEntityMeta();
meta.setFireworkInfo(ItemStack.of(Material.FIREWORK_ROCKET));
meta.setShooter(player);
player.addPassenger(firework);
})
.addListener(PlayerDisconnectEvent.class, event -> System.out.println("DISCONNECTION " + event.getPlayer().getUsername()))
.addListener(AsyncPlayerConfigurationEvent.class, event -> {
final Player player = event.getPlayer();
// Show off adding and removing feature flags
event.addFeatureFlag(FeatureFlag.BUNDLE);
event.addFeatureFlag(FeatureFlag.WINTER_DROP);
event.removeFeatureFlag(FeatureFlag.TRADE_REBALANCE); // not enabled by default, just removed for demonstration
var instances = MinecraftServer.getInstanceManager().getInstances();
@ -132,14 +120,13 @@ public class PlayerInit {
"hello", "world"
)));
player.setChestplate(ItemStack.of(Material.ELYTRA));
player.sendPacket(new ServerLinksPacket(
new ServerLinksPacket.Entry(ServerLinksPacket.KnownLinkType.NEWS, "https://minestom.net"),
new ServerLinksPacket.Entry(ServerLinksPacket.KnownLinkType.BUG_REPORT, "https://minestom.net"),
new ServerLinksPacket.Entry(Component.text("Hello world!"), "https://minestom.net")
));
// TODO(1.21.2): Handle bundle slot selection
ItemStack bundle = ItemStack.builder(Material.BUNDLE)
.set(ItemComponent.BUNDLE_CONTENTS, List.of(
ItemStack.of(Material.DIAMOND, 5),
@ -148,38 +135,19 @@ public class PlayerInit {
.build();
player.getInventory().addItemStack(bundle);
player.getInventory().addItemStack(ItemStack.builder(Material.COMPASS)
.set(ItemComponent.LODESTONE_TRACKER, new LodestoneTracker(player.getInstance().getDimensionName(), new Vec(10, 10, 10), true))
.build());
player.getInventory().addItemStack(ItemStack.builder(Material.STONE_SWORD)
.set(ItemComponent.ENCHANTMENTS, new EnchantmentList(Map.of(
Enchantment.SHARPNESS, 10
)))
.build());
player.getInventory().addItemStack(ItemStack.builder(Material.STONE_SWORD)
.build());
player.getInventory().addItemStack(ItemStack.builder(Material.BLACK_BANNER)
.build());
player.getInventory().addItemStack(ItemStack.builder(Material.POTION)
.set(ItemComponent.POTION_CONTENTS, new PotionContents(null, null, List.of(
new CustomPotionEffect(PotionEffect.JUMP_BOOST, new CustomPotionEffect.Settings((byte) 4,
45 * 20, false, true, true, null))
)))
.customName(Component.text("Sharpness 10 Sword").append(Component.space()).append(Component.text("§c§l[LEGENDARY]")))
.build());
player.setGameMode(GameMode.SURVIVAL);
PlayerInventory inventory = event.getPlayer().getInventory();
inventory.addItemStack(getFoodItem(20));
inventory.addItemStack(getFoodItem(10000));
inventory.addItemStack(getFoodItem(Integer.MAX_VALUE));
if (event.isFirstSpawn()) {
Notification notification = new Notification(
event.getPlayer().sendNotification(new Notification(
Component.text("Welcome!"),
FrameType.TASK,
Material.IRON_SWORD
);
NotificationCenter.send(notification, event.getPlayer());
));
player.playSound(Sound.sound(SoundEvent.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.Source.PLAYER, 0.5f, 1f));
}
@ -192,7 +160,7 @@ public class PlayerInit {
//System.out.println("in " + event.getPacket().getClass().getSimpleName());
})
.addListener(PlayerUseItemOnBlockEvent.class, event -> {
if (event.getHand() != Player.Hand.MAIN) return;
if (event.getHand() != PlayerHand.MAIN) return;
var itemStack = event.getItemStack();
var block = event.getInstance().getBlock(event.getPosition());
@ -206,16 +174,42 @@ public class PlayerInit {
event.getInstance().setBlock(event.getPosition(), block);
})
.addListener(PlayerBlockPlaceEvent.class, event -> {
// event.setDoBlockUpdates(false);
.addListener(PlayerBeginItemUseEvent.class, event -> {
final Player player = event.getPlayer();
final ItemStack itemStack = event.getItemStack();
final boolean hasProjectile = !itemStack.get(ItemComponent.CHARGED_PROJECTILES, List.of()).isEmpty();
if (itemStack.material() == Material.CROSSBOW && hasProjectile) {
// "shoot" the arrow
player.setItemInHand(event.getHand(), itemStack.without(ItemComponent.CHARGED_PROJECTILES));
event.getPlayer().sendMessage("pew pew!");
event.setItemUseDuration(0); // Do not start using the item
return;
}
})
.addListener(PlayerFinishItemUseEvent.class, event -> {
if (event.getItemStack().material() == Material.APPLE) {
event.getPlayer().sendMessage("yummy yummy apple");
}
})
.addListener(PlayerCancelItemUseEvent.class, event -> {
final Player player = event.getPlayer();
final ItemStack itemStack = event.getItemStack();
if (itemStack.material() == Material.CROSSBOW && event.getUseDuration() > 25) {
player.setItemInHand(event.getHand(), itemStack.with(ItemComponent.CHARGED_PROJECTILES, List.of(ItemStack.of(Material.ARROW))));
return;
}
})
.addListener(PlayerBlockInteractEvent.class, event -> {
var block = event.getBlock();
var rawOpenProp = block.getProperty("open");
if (rawOpenProp == null) return;
if (rawOpenProp != null) {
block = block.withProperty("open", String.valueOf(!Boolean.parseBoolean(rawOpenProp)));
event.getInstance().setBlock(event.getBlockPosition(), block);
}
block = block.withProperty("open", String.valueOf(!Boolean.parseBoolean(rawOpenProp)));
event.getInstance().setBlock(event.getBlockPosition(), block);
if (block.id() == Block.CRAFTING_TABLE.id()) {
event.getPlayer().openInventory(new Inventory(InventoryType.CRAFTING, "Crafting"));
}
});
{
@ -233,22 +227,6 @@ public class PlayerInit {
instanceContainer.setTimeRate(0);
instanceContainer.setTime(12000);
// var i2 = new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD, null, NamespaceID.from("minestom:demo"));
// instanceManager.registerInstance(i2);
// i2.setGenerator(unit -> unit.modifier().fillHeight(0, 40, Block.GRASS_BLOCK));
// i2.setChunkSupplier(LightingChunk::new);
// System.out.println("start");
// var chunks = new ArrayList<CompletableFuture<Chunk>>();
// ChunkUtils.forChunksInRange(0, 0, 32, (x, z) -> chunks.add(instanceContainer.loadChunk(x, z)));
// CompletableFuture.runAsync(() -> {
// CompletableFuture.allOf(chunks.toArray(CompletableFuture[]::new)).join();
// System.out.println("load end");
// LightingChunk.relight(instanceContainer, instanceContainer.getChunks());
// System.out.println("light end");
// });
inventory = new Inventory(InventoryType.CHEST_1_ROW, Component.text("Test inventory"));
inventory.setItemStack(3, ItemStack.of(Material.DIAMOND, 34));
}
@ -282,4 +260,16 @@ public class PlayerInit {
Audiences.players().sendPlayerListHeaderAndFooter(header, footer);
}).repeat(10, TimeUnit.SERVER_TICK).schedule();
}
public static ItemStack getFoodItem(int consumeTicks) {
return ItemStack.builder(Material.IRON_NUGGET)
.amount(64)
.set(ItemComponent.CONSUMABLE, new Consumable(
(float) consumeTicks / 20,
ItemAnimation.EAT,
SoundEvent.BLOCK_CHAIN_STEP,
true,
new ArrayList<>()))
.build();
}
}

View File

@ -0,0 +1,115 @@
package net.minestom.demo.commands;
import net.kyori.adventure.text.Component;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.arguments.ArgumentLiteral;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.arguments.minecraft.ArgumentEntity;
import net.minestom.server.command.builder.arguments.minecraft.ArgumentResource;
import net.minestom.server.command.builder.arguments.number.ArgumentDouble;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.entity.attribute.Attribute;
import net.minestom.server.utils.entity.EntityFinder;
import net.minestom.server.utils.identity.NamedAndIdentified;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.Component.translatable;
public class AttributeCommand extends Command {
public AttributeCommand() {
super("attribute");
ArgumentEntity target = ArgumentType.Entity("target").singleEntity(true);
ArgumentResource attribute = ArgumentType.Resource("attribute", "minecraft:attribute");
ArgumentLiteral base = ArgumentType.Literal("base");
ArgumentLiteral get = ArgumentType.Literal("get");
ArgumentLiteral set = ArgumentType.Literal("set");
ArgumentDouble value = ArgumentType.Double("value");
addSyntax(this::get, target, attribute, get);
addSyntax(this::setBase, target, attribute, base, set, value);
addSyntax(this::getBase, target, attribute, base, get);
}
private void setBase(CommandSender sender, CommandContext ctx) {
LivingEntity target = target(sender, ctx);
if (check(target, ctx, sender)) return;
Attribute attribute = attribute(ctx);
if (check(attribute, ctx, sender)) return;
double value = value(ctx);
target.getAttribute(attribute).setBaseValue(value);
sender.sendMessage(translatable("commands.attribute.base_value.set.success").arguments(description(attribute), name(target), text(value)));
}
private void getBase(CommandSender sender, CommandContext ctx) {
LivingEntity target = target(sender, ctx);
if (check(target, ctx, sender)) return;
Attribute attribute = attribute(ctx);
if (check(attribute, ctx, sender)) return;
double value = target.getAttribute(attribute).getBaseValue();
sender.sendMessage(translatable("commands.attribute.base_value.get.success").arguments(description(attribute), name(target), text(value)));
}
private void get(CommandSender sender, CommandContext ctx) {
LivingEntity target = target(sender, ctx);
if (check(target, ctx, sender)) return;
Attribute attribute = attribute(ctx);
if (check(attribute, ctx, sender)) return;
double value = target.getAttributeValue(attribute);
sender.sendMessage(translatable("commands.attribute.value.get.success").arguments(description(attribute), name(target), text(value)));
}
private Component description(Attribute attribute) {
return translatable(attribute.registry().translationKey());
}
private double value(CommandContext ctx) {
return ctx.get("value");
}
private LivingEntity target(CommandSender sender, CommandContext ctx) {
EntityFinder finder = ctx.get("target");
Entity entity = finder.findFirstEntity(sender);
if (!(entity instanceof LivingEntity livingEntity)) {
return null;
}
return livingEntity;
}
@Nullable
private Attribute attribute(CommandContext ctx) {
String namespaceId = ctx.get("attribute");
return Attribute.fromNamespaceId(namespaceId);
}
private Component name(Entity entity) {
if (entity instanceof NamedAndIdentified named) {
return named.getName();
}
return entity.getCustomName() == null ? entity.getCustomName() : text(entity.getEntityType().name());
}
@Contract("!null, _, _ -> false; null, _, _ -> true")
private boolean check(@Nullable LivingEntity livingEntity, CommandContext ctx, CommandSender sender) {
if (livingEntity == null) {
Entity entity = ctx.get("target");
sender.sendMessage(translatable("commands.attribute.failed.entity").arguments(name(entity)));
return true;
}
return false;
}
@Contract("!null, _, _ -> false; null, _, _ -> true")
private boolean check(@Nullable Attribute attribute, CommandContext ctx, CommandSender sender) {
if (attribute == null) {
sender.sendMessage(translatable("argument.resource.invalid_type").arguments(text(ctx.<String>get("attribute")), text("minecraft:attribute"), text("minecraft:attribute")));
return true;
}
return false;
}
}

View File

@ -33,7 +33,6 @@ public class FindCommand extends Command {
for (Entity entity : entities) {
player.sendMessage(" " + entity.getEntityType() + ": ");
player.sendMessage(" Meta: " + entity.getEntityMeta());
player.sendMessage(" Permissions: " + entity.getAllPermissions());
player.sendMessage(" Position: " + entity.getPosition());
}

View File

@ -53,7 +53,6 @@ public class GamemodeCommand extends Command {
return;
}
//Check permission, this could be replaced with hasPermission
if (p.getPermissionLevel() < 2) {
sender.sendMessage(Component.text("You don't have permission to use this command.", NamedTextColor.RED));
return;

View File

@ -2,12 +2,10 @@ package net.minestom.demo.commands;
import net.kyori.adventure.text.Component;
import net.minestom.server.advancements.FrameType;
import net.minestom.server.advancements.notifications.Notification;
import net.minestom.server.advancements.notifications.NotificationCenter;
import net.minestom.server.advancements.Notification;
import net.minestom.server.command.builder.Command;
import net.minestom.server.entity.Player;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class NotificationCommand extends Command {
public NotificationCommand() {
@ -15,9 +13,10 @@ public class NotificationCommand extends Command {
setDefaultExecutor((sender, context) -> {
var player = (Player) sender;
var notification = new Notification(Component.text("Hello World!"), FrameType.GOAL, Material.DIAMOND_AXE);
NotificationCenter.send(notification, player);
player.sendNotification(new Notification(
Component.text("Hello World!"),
FrameType.GOAL,
Material.DIAMOND_AXE));
});
}
}

View File

@ -0,0 +1,142 @@
package net.minestom.demo.commands;
import net.kyori.adventure.text.Component;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.arguments.number.ArgumentInteger;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.batch.RelativeBlockBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.component.EnchantmentList;
import net.minestom.server.item.enchant.Enchantment;
import net.minestom.server.potion.Potion;
import net.minestom.server.potion.PotionEffect;
import java.util.ArrayList;
import java.util.List;
public class TestInstabreakCommand extends Command {
public TestInstabreakCommand() {
super("testinstabreak");
ArgumentInteger level = ArgumentType.Integer("level");
addConditionalSyntax((sender, commandString) -> sender instanceof Player, (sender, context) -> {
Player player = (Player) sender;
int l = context.get(level);
player.removeEffect(PotionEffect.HASTE);
if (l != 0) {
player.addEffect(new Potion(PotionEffect.HASTE, (byte) (l - 1), -1));
}
}, ArgumentType.Literal("haste"), level);
addConditionalSyntax((sender, commandString) -> sender instanceof Player, (sender, context) -> {
Player player = (Player) sender;
int l = context.get(level);
player.removeEffect(PotionEffect.CONDUIT_POWER);
if (l != 0) {
player.addEffect(new Potion(PotionEffect.CONDUIT_POWER, (byte) (l - 1), -1));
}
}, ArgumentType.Literal("conduit"), level);
addConditionalSyntax((sender, commandString) -> sender instanceof Player, (sender, context) -> {
Player player = (Player) sender;
int l = context.get(level);
player.removeEffect(PotionEffect.MINING_FATIGUE);
if (l != 0) {
player.addEffect(new Potion(PotionEffect.MINING_FATIGUE, (byte) (l - 1), -1));
}
}, ArgumentType.Literal("fatigue"), level);
addConditionalSyntax((sender, commandString) -> sender instanceof Player, (sender, context) -> {
Player player = (Player) sender;
giveItems(player);
}, ArgumentType.Literal("giveItems"));
addConditionalSyntax((sender, commandString) -> sender instanceof Player, (sender, context) -> {
Player player = (Player) sender;
player.openInventory(new Inventory(InventoryType.ANVIL, Component.translatable("container.repair")));
}, ArgumentType.Literal("anvil"));
RelativeBlockBatch areaBatch = new RelativeBlockBatch();
for (int x = -20; x < 21; x++) {
for (int z = -20; z < 21; z++) {
for (int y = -10; y < 0; y++) {
areaBatch.setBlock(x, y, z, Block.WHITE_WOOL);
}
}
}
areaBatch.setBlock(2, 0, 0, Block.WATER);
areaBatch.setBlock(3, 0, 0, Block.WATER);
areaBatch.setBlock(2, 0, 1, Block.WATER);
areaBatch.setBlock(3, 0, 1, Block.WATER);
areaBatch.setBlock(5, 1, 0, Block.WATER);
areaBatch.setBlock(6, 1, 0, Block.WATER);
areaBatch.setBlock(5, 1, 1, Block.WATER);
areaBatch.setBlock(6, 1, 1, Block.WATER);
areaBatch.setBlock(8, 1, 1, Block.WATER.withProperty("level", "0"));
areaBatch.setBlock(10, 1, 1, Block.WATER.withProperty("level", "1"));
areaBatch.setBlock(8, 1, 3, Block.WATER.withProperty("level", "2"));
areaBatch.setBlock(10, 1, 3, Block.WATER.withProperty("level", "3"));
areaBatch.setBlock(8, 1, 5, Block.WATER.withProperty("level", "4"));
areaBatch.setBlock(10, 1, 5, Block.WATER.withProperty("level", "5"));
areaBatch.setBlock(8, 1, 7, Block.WATER.withProperty("level", "6"));
areaBatch.setBlock(10, 1, 7, Block.WATER.withProperty("level", "7"));
areaBatch.setBlock(8, 1, 9, Block.WATER.withProperty("level", "8"));
areaBatch.setBlock(10, 1, 9, Block.WATER.withProperty("level", "13"));
for (int x = -3; x < 0; x++) {
for (int z = -3; z < 0; z++) {
for (int y = 0; y < 4; y++) {
areaBatch.setBlock(x, y, z, Block.WATER);
}
}
}
for (int x = -9; x < -6; x++) {
for (int z = -9; z < -6; z++) {
for (int y = 0; y < 3; y++) {
areaBatch.setBlock(x, y, z, Block.BAMBOO);
}
areaBatch.setBlock(x, 3, z, Block.BAMBOO_SAPLING);
}
}
addConditionalSyntax((sender, commandString) -> sender instanceof Player, (sender, context) -> {
Player player = (Player) sender;
areaBatch.apply(player.getInstance(), player.getPosition(), null);
}, ArgumentType.Literal("placeArea"));
addConditionalSyntax((sender, commandString) -> sender instanceof Player, (sender, context) -> {
Player player = (Player) sender;
boolean state = context.get("state");
player.setInstantBreak(state);
}, ArgumentType.Literal("instabreak"), ArgumentType.Boolean("state"));
addConditionalSyntax((sender, commandString) -> sender instanceof Player, (sender, context) -> {
Player player = (Player) sender;
player.setGameMode(GameMode.SURVIVAL);
player.getInventory().clear();
giveItems(player);
areaBatch.apply(player.getInstance(), player.getPosition(), null);
});
}
private void giveItems(Player player) {
List<ItemStack> items = new ArrayList<>();
items.add(ItemStack.builder(Material.SHEARS).set(ItemComponent.ENCHANTMENTS, EnchantmentList.EMPTY.with(Enchantment.EFFICIENCY, 5)).build());
items.add(ItemStack.builder(Material.WHITE_WOOL).amount(64).build());
items.add(ItemStack.builder(Material.STONE).amount(64).build());
items.add(ItemStack.of(Material.DIAMOND_SWORD));
items.add(ItemStack.of(Material.DIAMOND_PICKAXE));
for (ItemStack item : items) {
player.getInventory().addItemStack(item);
}
}
}

View File

@ -35,7 +35,7 @@ public class ChickenCreature extends EntityCreature {
// .build()
// );
getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.1);
getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.1);
}
@Override

View File

@ -0,0 +1,34 @@
package net.minestom.demo.recipe;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.recipe.Ingredient;
import net.minestom.server.recipe.Recipe;
import net.minestom.server.recipe.RecipeBookCategory;
import net.minestom.server.recipe.display.RecipeDisplay;
import net.minestom.server.recipe.display.SlotDisplay;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public record ShapelessRecipe(
@NotNull RecipeBookCategory recipeBookCategory,
@NotNull List<Material> ingredients,
@NotNull ItemStack result
) implements Recipe {
@Override
public @NotNull List<RecipeDisplay> createRecipeDisplays() {
return List.of(new RecipeDisplay.CraftingShapeless(
ingredients.stream().map(item -> (SlotDisplay) new SlotDisplay.Item(item)).toList(),
new SlotDisplay.ItemStack(result),
new SlotDisplay.Item(Material.CRAFTING_TABLE)
));
}
@Override
public @NotNull List<Ingredient> craftingRequirements() {
return List.of(new Ingredient(ingredients));
}
}

View File

@ -3,13 +3,12 @@ metadata.format.version = "1.1"
[versions]
# Important dependencies
data = "1.21-rv3"
data = "1.21.3-rv2"
adventure = "4.17.0"
jetbrainsAnnotations = "24.1.0"
slf4j = "2.0.7"
# Performance / Data Structures
caffeine = "3.1.8"
fastutil = "8.5.14"
flare = "2.0.1"
gson = "2.11.0"
@ -49,7 +48,6 @@ jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version.
slf4j = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j"}
# Performance / Data Structures
caffeine = { group = "com.github.ben-manes.caffeine", name = "caffeine", version.ref = "caffeine" }
fastutil = { group = "it.unimi.dsi", name = "fastutil", version.ref = "fastutil" }
flare = { group = "space.vectrix.flare", name = "flare", version.ref = "flare" }
flare-fastutil = { group = "space.vectrix.flare", name = "flare-fastutil", version.ref = "flare" }

View File

@ -1,6 +1,7 @@
package net.minestom.server.utils;
import net.minestom.server.utils.binary.BinaryBuffer;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.PacketVanilla;
import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.L_Result;
@ -11,7 +12,7 @@ import static org.openjdk.jcstress.annotations.Expect.ACCEPTABLE;
@Outcome(id = "2", expect = ACCEPTABLE)
@State
public class ObjectPoolTest {
private final ObjectPool<BinaryBuffer> pool = ObjectPool.BUFFER_POOL;
private final ObjectPool<NetworkBuffer> pool = PacketVanilla.PACKET_POOL;
@Actor
public void actor1() {

View File

@ -5,9 +5,13 @@ package net.minestom.server;
*/
@SuppressWarnings("unused")
interface FeatureFlags {
FeatureFlag BUNDLE = FeatureFlagImpl.get("minecraft:bundle");
FeatureFlag REDSTONE_EXPERIMENTS = FeatureFlagImpl.get("minecraft:redstone_experiments");
FeatureFlag VANILLA = FeatureFlagImpl.get("minecraft:vanilla");
FeatureFlag WINTER_DROP = FeatureFlagImpl.get("minecraft:winter_drop");
FeatureFlag TRADE_REBALANCE = FeatureFlagImpl.get("minecraft:trade_rebalance");
FeatureFlag MINECART_IMPROVEMENTS = FeatureFlagImpl.get("minecraft:minecart_improvements");
}

View File

@ -4,13 +4,13 @@ package net.minestom.server;
* AUTOGENERATED by ConstantsGenerator
*/
interface MinecraftConstants {
String VERSION_NAME = "1.21";
String VERSION_NAME = "1.21.3";
int PROTOCOL_VERSION = 767;
int PROTOCOL_VERSION = 768;
int DATA_VERSION = 3953;
int DATA_VERSION = 4082;
int RESOURCE_PACK_VERSION = 34;
int RESOURCE_PACK_VERSION = 42;
int DATA_PACK_VERSION = 48;
int DATA_PACK_VERSION = 57;
}

View File

@ -0,0 +1,141 @@
package net.minestom.server.command;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;
/**
* AUTOGENERATED by GenericEnumGenerator
*/
public enum ArgumentParserType implements StaticProtocolObject {
BOOL(NamespaceID.from("brigadier:bool")),
FLOAT(NamespaceID.from("brigadier:float")),
DOUBLE(NamespaceID.from("brigadier:double")),
INTEGER(NamespaceID.from("brigadier:integer")),
LONG(NamespaceID.from("brigadier:long")),
STRING(NamespaceID.from("brigadier:string")),
ENTITY(NamespaceID.from("minecraft:entity")),
GAME_PROFILE(NamespaceID.from("minecraft:game_profile")),
BLOCK_POS(NamespaceID.from("minecraft:block_pos")),
COLUMN_POS(NamespaceID.from("minecraft:column_pos")),
VEC3(NamespaceID.from("minecraft:vec3")),
VEC2(NamespaceID.from("minecraft:vec2")),
BLOCK_STATE(NamespaceID.from("minecraft:block_state")),
BLOCK_PREDICATE(NamespaceID.from("minecraft:block_predicate")),
ITEM_STACK(NamespaceID.from("minecraft:item_stack")),
ITEM_PREDICATE(NamespaceID.from("minecraft:item_predicate")),
COLOR(NamespaceID.from("minecraft:color")),
COMPONENT(NamespaceID.from("minecraft:component")),
STYLE(NamespaceID.from("minecraft:style")),
MESSAGE(NamespaceID.from("minecraft:message")),
NBT_COMPOUND_TAG(NamespaceID.from("minecraft:nbt_compound_tag")),
NBT_TAG(NamespaceID.from("minecraft:nbt_tag")),
NBT_PATH(NamespaceID.from("minecraft:nbt_path")),
OBJECTIVE(NamespaceID.from("minecraft:objective")),
OBJECTIVE_CRITERIA(NamespaceID.from("minecraft:objective_criteria")),
OPERATION(NamespaceID.from("minecraft:operation")),
PARTICLE(NamespaceID.from("minecraft:particle")),
ANGLE(NamespaceID.from("minecraft:angle")),
ROTATION(NamespaceID.from("minecraft:rotation")),
SCOREBOARD_SLOT(NamespaceID.from("minecraft:scoreboard_slot")),
SCORE_HOLDER(NamespaceID.from("minecraft:score_holder")),
SWIZZLE(NamespaceID.from("minecraft:swizzle")),
TEAM(NamespaceID.from("minecraft:team")),
ITEM_SLOT(NamespaceID.from("minecraft:item_slot")),
ITEM_SLOTS(NamespaceID.from("minecraft:item_slots")),
RESOURCE_LOCATION(NamespaceID.from("minecraft:resource_location")),
FUNCTION(NamespaceID.from("minecraft:function")),
ENTITY_ANCHOR(NamespaceID.from("minecraft:entity_anchor")),
INT_RANGE(NamespaceID.from("minecraft:int_range")),
FLOAT_RANGE(NamespaceID.from("minecraft:float_range")),
DIMENSION(NamespaceID.from("minecraft:dimension")),
GAMEMODE(NamespaceID.from("minecraft:gamemode")),
TIME(NamespaceID.from("minecraft:time")),
RESOURCE_OR_TAG(NamespaceID.from("minecraft:resource_or_tag")),
RESOURCE_OR_TAG_KEY(NamespaceID.from("minecraft:resource_or_tag_key")),
RESOURCE(NamespaceID.from("minecraft:resource")),
RESOURCE_KEY(NamespaceID.from("minecraft:resource_key")),
TEMPLATE_MIRROR(NamespaceID.from("minecraft:template_mirror")),
TEMPLATE_ROTATION(NamespaceID.from("minecraft:template_rotation")),
HEIGHTMAP(NamespaceID.from("minecraft:heightmap")),
LOOT_TABLE(NamespaceID.from("minecraft:loot_table")),
LOOT_PREDICATE(NamespaceID.from("minecraft:loot_predicate")),
LOOT_MODIFIER(NamespaceID.from("minecraft:loot_modifier")),
UUID(NamespaceID.from("minecraft:uuid"));
public static final NetworkBuffer.Type<ArgumentParserType> NETWORK_TYPE = NetworkBuffer.Enum(ArgumentParserType.class);
public static final BinaryTagSerializer<ArgumentParserType> NBT_TYPE = BinaryTagSerializer.fromEnumKeyed(ArgumentParserType.class);
private final NamespaceID namespace;
ArgumentParserType(@NotNull NamespaceID namespace) {
this.namespace = namespace;
}
@NotNull
@Override
public NamespaceID namespace() {
return this.namespace;
}
@Override
public int id() {
return this.ordinal();
}
}

View File

@ -5,6 +5,10 @@ package net.minestom.server.entity;
*/
@SuppressWarnings("unused")
interface EntityTypes {
EntityType ACACIA_BOAT = EntityTypeImpl.get("minecraft:acacia_boat");
EntityType ACACIA_CHEST_BOAT = EntityTypeImpl.get("minecraft:acacia_chest_boat");
EntityType ALLAY = EntityTypeImpl.get("minecraft:allay");
EntityType AREA_EFFECT_CLOUD = EntityTypeImpl.get("minecraft:area_effect_cloud");
@ -17,16 +21,22 @@ interface EntityTypes {
EntityType AXOLOTL = EntityTypeImpl.get("minecraft:axolotl");
EntityType BAMBOO_CHEST_RAFT = EntityTypeImpl.get("minecraft:bamboo_chest_raft");
EntityType BAMBOO_RAFT = EntityTypeImpl.get("minecraft:bamboo_raft");
EntityType BAT = EntityTypeImpl.get("minecraft:bat");
EntityType BEE = EntityTypeImpl.get("minecraft:bee");
EntityType BIRCH_BOAT = EntityTypeImpl.get("minecraft:birch_boat");
EntityType BIRCH_CHEST_BOAT = EntityTypeImpl.get("minecraft:birch_chest_boat");
EntityType BLAZE = EntityTypeImpl.get("minecraft:blaze");
EntityType BLOCK_DISPLAY = EntityTypeImpl.get("minecraft:block_display");
EntityType BOAT = EntityTypeImpl.get("minecraft:boat");
EntityType BOGGED = EntityTypeImpl.get("minecraft:bogged");
EntityType BREEZE = EntityTypeImpl.get("minecraft:breeze");
@ -39,7 +49,9 @@ interface EntityTypes {
EntityType CAVE_SPIDER = EntityTypeImpl.get("minecraft:cave_spider");
EntityType CHEST_BOAT = EntityTypeImpl.get("minecraft:chest_boat");
EntityType CHERRY_BOAT = EntityTypeImpl.get("minecraft:cherry_boat");
EntityType CHERRY_CHEST_BOAT = EntityTypeImpl.get("minecraft:cherry_chest_boat");
EntityType CHEST_MINECART = EntityTypeImpl.get("minecraft:chest_minecart");
@ -51,8 +63,16 @@ interface EntityTypes {
EntityType COW = EntityTypeImpl.get("minecraft:cow");
EntityType CREAKING = EntityTypeImpl.get("minecraft:creaking");
EntityType CREAKING_TRANSIENT = EntityTypeImpl.get("minecraft:creaking_transient");
EntityType CREEPER = EntityTypeImpl.get("minecraft:creeper");
EntityType DARK_OAK_BOAT = EntityTypeImpl.get("minecraft:dark_oak_boat");
EntityType DARK_OAK_CHEST_BOAT = EntityTypeImpl.get("minecraft:dark_oak_chest_boat");
EntityType DOLPHIN = EntityTypeImpl.get("minecraft:dolphin");
EntityType DONKEY = EntityTypeImpl.get("minecraft:donkey");
@ -65,15 +85,15 @@ interface EntityTypes {
EntityType ELDER_GUARDIAN = EntityTypeImpl.get("minecraft:elder_guardian");
EntityType END_CRYSTAL = EntityTypeImpl.get("minecraft:end_crystal");
EntityType ENDERMAN = EntityTypeImpl.get("minecraft:enderman");
EntityType ENDERMITE = EntityTypeImpl.get("minecraft:endermite");
EntityType ENDER_DRAGON = EntityTypeImpl.get("minecraft:ender_dragon");
EntityType ENDER_PEARL = EntityTypeImpl.get("minecraft:ender_pearl");
EntityType ENDERMAN = EntityTypeImpl.get("minecraft:enderman");
EntityType ENDERMITE = EntityTypeImpl.get("minecraft:endermite");
EntityType END_CRYSTAL = EntityTypeImpl.get("minecraft:end_crystal");
EntityType EVOKER = EntityTypeImpl.get("minecraft:evoker");
@ -87,6 +107,8 @@ interface EntityTypes {
EntityType FALLING_BLOCK = EntityTypeImpl.get("minecraft:falling_block");
EntityType FIREBALL = EntityTypeImpl.get("minecraft:fireball");
EntityType FIREWORK_ROCKET = EntityTypeImpl.get("minecraft:firework_rocket");
EntityType FOX = EntityTypeImpl.get("minecraft:fox");
@ -127,9 +149,9 @@ interface EntityTypes {
EntityType ITEM_FRAME = EntityTypeImpl.get("minecraft:item_frame");
EntityType OMINOUS_ITEM_SPAWNER = EntityTypeImpl.get("minecraft:ominous_item_spawner");
EntityType JUNGLE_BOAT = EntityTypeImpl.get("minecraft:jungle_boat");
EntityType FIREBALL = EntityTypeImpl.get("minecraft:fireball");
EntityType JUNGLE_CHEST_BOAT = EntityTypeImpl.get("minecraft:jungle_chest_boat");
EntityType LEASH_KNOT = EntityTypeImpl.get("minecraft:leash_knot");
@ -141,6 +163,10 @@ interface EntityTypes {
EntityType MAGMA_CUBE = EntityTypeImpl.get("minecraft:magma_cube");
EntityType MANGROVE_BOAT = EntityTypeImpl.get("minecraft:mangrove_boat");
EntityType MANGROVE_CHEST_BOAT = EntityTypeImpl.get("minecraft:mangrove_chest_boat");
EntityType MARKER = EntityTypeImpl.get("minecraft:marker");
EntityType MINECART = EntityTypeImpl.get("minecraft:minecart");
@ -149,10 +175,20 @@ interface EntityTypes {
EntityType MULE = EntityTypeImpl.get("minecraft:mule");
EntityType OAK_BOAT = EntityTypeImpl.get("minecraft:oak_boat");
EntityType OAK_CHEST_BOAT = EntityTypeImpl.get("minecraft:oak_chest_boat");
EntityType OCELOT = EntityTypeImpl.get("minecraft:ocelot");
EntityType OMINOUS_ITEM_SPAWNER = EntityTypeImpl.get("minecraft:ominous_item_spawner");
EntityType PAINTING = EntityTypeImpl.get("minecraft:painting");
EntityType PALE_OAK_BOAT = EntityTypeImpl.get("minecraft:pale_oak_boat");
EntityType PALE_OAK_CHEST_BOAT = EntityTypeImpl.get("minecraft:pale_oak_chest_boat");
EntityType PANDA = EntityTypeImpl.get("minecraft:panda");
EntityType PARROT = EntityTypeImpl.get("minecraft:parrot");
@ -197,16 +233,20 @@ interface EntityTypes {
EntityType SNIFFER = EntityTypeImpl.get("minecraft:sniffer");
EntityType SNOW_GOLEM = EntityTypeImpl.get("minecraft:snow_golem");
EntityType SNOWBALL = EntityTypeImpl.get("minecraft:snowball");
EntityType SNOW_GOLEM = EntityTypeImpl.get("minecraft:snow_golem");
EntityType SPAWNER_MINECART = EntityTypeImpl.get("minecraft:spawner_minecart");
EntityType SPECTRAL_ARROW = EntityTypeImpl.get("minecraft:spectral_arrow");
EntityType SPIDER = EntityTypeImpl.get("minecraft:spider");
EntityType SPRUCE_BOAT = EntityTypeImpl.get("minecraft:spruce_boat");
EntityType SPRUCE_CHEST_BOAT = EntityTypeImpl.get("minecraft:spruce_chest_boat");
EntityType SQUID = EntityTypeImpl.get("minecraft:squid");
EntityType STRAY = EntityTypeImpl.get("minecraft:stray");

View File

@ -0,0 +1,37 @@
package net.minestom.server.entity;
/**
* Code autogenerated, do not edit!
*/
@SuppressWarnings("unused")
interface VillagerProfessions {
VillagerProfession NONE = VillagerProfessionImpl.get("minecraft:none");
VillagerProfession ARMORER = VillagerProfessionImpl.get("minecraft:armorer");
VillagerProfession BUTCHER = VillagerProfessionImpl.get("minecraft:butcher");
VillagerProfession CARTOGRAPHER = VillagerProfessionImpl.get("minecraft:cartographer");
VillagerProfession CLERIC = VillagerProfessionImpl.get("minecraft:cleric");
VillagerProfession FARMER = VillagerProfessionImpl.get("minecraft:farmer");
VillagerProfession FISHERMAN = VillagerProfessionImpl.get("minecraft:fisherman");
VillagerProfession FLETCHER = VillagerProfessionImpl.get("minecraft:fletcher");
VillagerProfession LEATHERWORKER = VillagerProfessionImpl.get("minecraft:leatherworker");
VillagerProfession LIBRARIAN = VillagerProfessionImpl.get("minecraft:librarian");
VillagerProfession MASON = VillagerProfessionImpl.get("minecraft:mason");
VillagerProfession NITWIT = VillagerProfessionImpl.get("minecraft:nitwit");
VillagerProfession SHEPHERD = VillagerProfessionImpl.get("minecraft:shepherd");
VillagerProfession TOOLSMITH = VillagerProfessionImpl.get("minecraft:toolsmith");
VillagerProfession WEAPONSMITH = VillagerProfessionImpl.get("minecraft:weaponsmith");
}

View File

@ -0,0 +1,47 @@
package net.minestom.server.entity;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;
/**
* AUTOGENERATED by GenericEnumGenerator
*/
public enum VillagerType implements StaticProtocolObject {
DESERT(NamespaceID.from("minecraft:desert")),
JUNGLE(NamespaceID.from("minecraft:jungle")),
PLAINS(NamespaceID.from("minecraft:plains")),
SAVANNA(NamespaceID.from("minecraft:savanna")),
SNOW(NamespaceID.from("minecraft:snow")),
SWAMP(NamespaceID.from("minecraft:swamp")),
TAIGA(NamespaceID.from("minecraft:taiga"));
public static final NetworkBuffer.Type<VillagerType> NETWORK_TYPE = NetworkBuffer.Enum(VillagerType.class);
public static final BinaryTagSerializer<VillagerType> NBT_TYPE = BinaryTagSerializer.fromEnumKeyed(VillagerType.class);
private final NamespaceID namespace;
VillagerType(@NotNull NamespaceID namespace) {
this.namespace = namespace;
}
@NotNull
@Override
public NamespaceID namespace() {
return this.namespace;
}
@Override
public int id() {
return this.ordinal();
}
}

View File

@ -5,65 +5,67 @@ package net.minestom.server.entity.attribute;
*/
@SuppressWarnings("unused")
interface Attributes {
Attribute GENERIC_ARMOR = AttributeImpl.get("minecraft:generic.armor");
Attribute ARMOR = AttributeImpl.get("minecraft:armor");
Attribute GENERIC_ARMOR_TOUGHNESS = AttributeImpl.get("minecraft:generic.armor_toughness");
Attribute ARMOR_TOUGHNESS = AttributeImpl.get("minecraft:armor_toughness");
Attribute GENERIC_ATTACK_DAMAGE = AttributeImpl.get("minecraft:generic.attack_damage");
Attribute ATTACK_DAMAGE = AttributeImpl.get("minecraft:attack_damage");
Attribute GENERIC_ATTACK_KNOCKBACK = AttributeImpl.get("minecraft:generic.attack_knockback");
Attribute ATTACK_KNOCKBACK = AttributeImpl.get("minecraft:attack_knockback");
Attribute GENERIC_ATTACK_SPEED = AttributeImpl.get("minecraft:generic.attack_speed");
Attribute ATTACK_SPEED = AttributeImpl.get("minecraft:attack_speed");
Attribute PLAYER_BLOCK_BREAK_SPEED = AttributeImpl.get("minecraft:player.block_break_speed");
Attribute BLOCK_BREAK_SPEED = AttributeImpl.get("minecraft:block_break_speed");
Attribute PLAYER_BLOCK_INTERACTION_RANGE = AttributeImpl.get("minecraft:player.block_interaction_range");
Attribute BLOCK_INTERACTION_RANGE = AttributeImpl.get("minecraft:block_interaction_range");
Attribute GENERIC_BURNING_TIME = AttributeImpl.get("minecraft:generic.burning_time");
Attribute BURNING_TIME = AttributeImpl.get("minecraft:burning_time");
Attribute GENERIC_EXPLOSION_KNOCKBACK_RESISTANCE = AttributeImpl.get("minecraft:generic.explosion_knockback_resistance");
Attribute EXPLOSION_KNOCKBACK_RESISTANCE = AttributeImpl.get("minecraft:explosion_knockback_resistance");
Attribute PLAYER_ENTITY_INTERACTION_RANGE = AttributeImpl.get("minecraft:player.entity_interaction_range");
Attribute ENTITY_INTERACTION_RANGE = AttributeImpl.get("minecraft:entity_interaction_range");
Attribute GENERIC_FALL_DAMAGE_MULTIPLIER = AttributeImpl.get("minecraft:generic.fall_damage_multiplier");
Attribute FALL_DAMAGE_MULTIPLIER = AttributeImpl.get("minecraft:fall_damage_multiplier");
Attribute GENERIC_FLYING_SPEED = AttributeImpl.get("minecraft:generic.flying_speed");
Attribute FLYING_SPEED = AttributeImpl.get("minecraft:flying_speed");
Attribute GENERIC_FOLLOW_RANGE = AttributeImpl.get("minecraft:generic.follow_range");
Attribute FOLLOW_RANGE = AttributeImpl.get("minecraft:follow_range");
Attribute GENERIC_GRAVITY = AttributeImpl.get("minecraft:generic.gravity");
Attribute GRAVITY = AttributeImpl.get("minecraft:gravity");
Attribute GENERIC_JUMP_STRENGTH = AttributeImpl.get("minecraft:generic.jump_strength");
Attribute JUMP_STRENGTH = AttributeImpl.get("minecraft:jump_strength");
Attribute GENERIC_KNOCKBACK_RESISTANCE = AttributeImpl.get("minecraft:generic.knockback_resistance");
Attribute KNOCKBACK_RESISTANCE = AttributeImpl.get("minecraft:knockback_resistance");
Attribute GENERIC_LUCK = AttributeImpl.get("minecraft:generic.luck");
Attribute LUCK = AttributeImpl.get("minecraft:luck");
Attribute GENERIC_MAX_ABSORPTION = AttributeImpl.get("minecraft:generic.max_absorption");
Attribute MAX_ABSORPTION = AttributeImpl.get("minecraft:max_absorption");
Attribute GENERIC_MAX_HEALTH = AttributeImpl.get("minecraft:generic.max_health");
Attribute MAX_HEALTH = AttributeImpl.get("minecraft:max_health");
Attribute PLAYER_MINING_EFFICIENCY = AttributeImpl.get("minecraft:player.mining_efficiency");
Attribute MINING_EFFICIENCY = AttributeImpl.get("minecraft:mining_efficiency");
Attribute GENERIC_MOVEMENT_EFFICIENCY = AttributeImpl.get("minecraft:generic.movement_efficiency");
Attribute MOVEMENT_EFFICIENCY = AttributeImpl.get("minecraft:movement_efficiency");
Attribute GENERIC_MOVEMENT_SPEED = AttributeImpl.get("minecraft:generic.movement_speed");
Attribute MOVEMENT_SPEED = AttributeImpl.get("minecraft:movement_speed");
Attribute GENERIC_OXYGEN_BONUS = AttributeImpl.get("minecraft:generic.oxygen_bonus");
Attribute OXYGEN_BONUS = AttributeImpl.get("minecraft:oxygen_bonus");
Attribute GENERIC_SAFE_FALL_DISTANCE = AttributeImpl.get("minecraft:generic.safe_fall_distance");
Attribute SAFE_FALL_DISTANCE = AttributeImpl.get("minecraft:safe_fall_distance");
Attribute GENERIC_SCALE = AttributeImpl.get("minecraft:generic.scale");
Attribute SCALE = AttributeImpl.get("minecraft:scale");
Attribute PLAYER_SNEAKING_SPEED = AttributeImpl.get("minecraft:player.sneaking_speed");
Attribute SNEAKING_SPEED = AttributeImpl.get("minecraft:sneaking_speed");
Attribute ZOMBIE_SPAWN_REINFORCEMENTS = AttributeImpl.get("minecraft:zombie.spawn_reinforcements");
Attribute SPAWN_REINFORCEMENTS = AttributeImpl.get("minecraft:spawn_reinforcements");
Attribute GENERIC_STEP_HEIGHT = AttributeImpl.get("minecraft:generic.step_height");
Attribute STEP_HEIGHT = AttributeImpl.get("minecraft:step_height");
Attribute PLAYER_SUBMERGED_MINING_SPEED = AttributeImpl.get("minecraft:player.submerged_mining_speed");
Attribute SUBMERGED_MINING_SPEED = AttributeImpl.get("minecraft:submerged_mining_speed");
Attribute PLAYER_SWEEPING_DAMAGE_RATIO = AttributeImpl.get("minecraft:player.sweeping_damage_ratio");
Attribute SWEEPING_DAMAGE_RATIO = AttributeImpl.get("minecraft:sweeping_damage_ratio");
Attribute GENERIC_WATER_MOVEMENT_EFFICIENCY = AttributeImpl.get("minecraft:generic.water_movement_efficiency");
Attribute TEMPT_RANGE = AttributeImpl.get("minecraft:tempt_range");
Attribute WATER_MOVEMENT_EFFICIENCY = AttributeImpl.get("minecraft:water_movement_efficiency");
}

View File

@ -9,44 +9,24 @@ import net.minestom.server.registry.DynamicRegistry;
interface DamageTypes {
DynamicRegistry.Key<DamageType> WITHER = DynamicRegistry.Key.of("minecraft:wither");
DynamicRegistry.Key<DamageType> SONIC_BOOM = DynamicRegistry.Key.of("minecraft:sonic_boom");
DynamicRegistry.Key<DamageType> WITHER_SKULL = DynamicRegistry.Key.of("minecraft:wither_skull");
DynamicRegistry.Key<DamageType> DRY_OUT = DynamicRegistry.Key.of("minecraft:dry_out");
DynamicRegistry.Key<DamageType> MACE_SMASH = DynamicRegistry.Key.of("minecraft:mace_smash");
DynamicRegistry.Key<DamageType> TRIDENT = DynamicRegistry.Key.of("minecraft:trident");
DynamicRegistry.Key<DamageType> ON_FIRE = DynamicRegistry.Key.of("minecraft:on_fire");
DynamicRegistry.Key<DamageType> FALL = DynamicRegistry.Key.of("minecraft:fall");
DynamicRegistry.Key<DamageType> MOB_ATTACK = DynamicRegistry.Key.of("minecraft:mob_attack");
DynamicRegistry.Key<DamageType> MOB_PROJECTILE = DynamicRegistry.Key.of("minecraft:mob_projectile");
DynamicRegistry.Key<DamageType> CAMPFIRE = DynamicRegistry.Key.of("minecraft:campfire");
DynamicRegistry.Key<DamageType> THROWN = DynamicRegistry.Key.of("minecraft:thrown");
DynamicRegistry.Key<DamageType> FALLING_STALACTITE = DynamicRegistry.Key.of("minecraft:falling_stalactite");
DynamicRegistry.Key<DamageType> FIREBALL = DynamicRegistry.Key.of("minecraft:fireball");
DynamicRegistry.Key<DamageType> FALLING_BLOCK = DynamicRegistry.Key.of("minecraft:falling_block");
DynamicRegistry.Key<DamageType> WIND_CHARGE = DynamicRegistry.Key.of("minecraft:wind_charge");
DynamicRegistry.Key<DamageType> PLAYER_EXPLOSION = DynamicRegistry.Key.of("minecraft:player_explosion");
DynamicRegistry.Key<DamageType> SPIT = DynamicRegistry.Key.of("minecraft:spit");
DynamicRegistry.Key<DamageType> STING = DynamicRegistry.Key.of("minecraft:sting");
DynamicRegistry.Key<DamageType> UNATTRIBUTED_FIREBALL = DynamicRegistry.Key.of("minecraft:unattributed_fireball");
DynamicRegistry.Key<DamageType> IN_WALL = DynamicRegistry.Key.of("minecraft:in_wall");
DynamicRegistry.Key<DamageType> IN_FIRE = DynamicRegistry.Key.of("minecraft:in_fire");
DynamicRegistry.Key<DamageType> ARROW = DynamicRegistry.Key.of("minecraft:arrow");
@ -55,42 +35,68 @@ interface DamageTypes {
DynamicRegistry.Key<DamageType> DROWN = DynamicRegistry.Key.of("minecraft:drown");
DynamicRegistry.Key<DamageType> STARVE = DynamicRegistry.Key.of("minecraft:starve");
DynamicRegistry.Key<DamageType> GENERIC_KILL = DynamicRegistry.Key.of("minecraft:generic_kill");
DynamicRegistry.Key<DamageType> DRAGON_BREATH = DynamicRegistry.Key.of("minecraft:dragon_breath");
DynamicRegistry.Key<DamageType> MOB_ATTACK_NO_AGGRO = DynamicRegistry.Key.of("minecraft:mob_attack_no_aggro");
DynamicRegistry.Key<DamageType> LAVA = DynamicRegistry.Key.of("minecraft:lava");
DynamicRegistry.Key<DamageType> OUTSIDE_BORDER = DynamicRegistry.Key.of("minecraft:outside_border");
DynamicRegistry.Key<DamageType> FLY_INTO_WALL = DynamicRegistry.Key.of("minecraft:fly_into_wall");
DynamicRegistry.Key<DamageType> LIGHTNING_BOLT = DynamicRegistry.Key.of("minecraft:lightning_bolt");
DynamicRegistry.Key<DamageType> PLAYER_ATTACK = DynamicRegistry.Key.of("minecraft:player_attack");
DynamicRegistry.Key<DamageType> FREEZE = DynamicRegistry.Key.of("minecraft:freeze");
DynamicRegistry.Key<DamageType> FALLING_ANVIL = DynamicRegistry.Key.of("minecraft:falling_anvil");
DynamicRegistry.Key<DamageType> OUT_OF_WORLD = DynamicRegistry.Key.of("minecraft:out_of_world");
DynamicRegistry.Key<DamageType> MAGIC = DynamicRegistry.Key.of("minecraft:magic");
DynamicRegistry.Key<DamageType> SWEET_BERRY_BUSH = DynamicRegistry.Key.of("minecraft:sweet_berry_bush");
DynamicRegistry.Key<DamageType> FIREWORKS = DynamicRegistry.Key.of("minecraft:fireworks");
DynamicRegistry.Key<DamageType> STALAGMITE = DynamicRegistry.Key.of("minecraft:stalagmite");
DynamicRegistry.Key<DamageType> GENERIC = DynamicRegistry.Key.of("minecraft:generic");
DynamicRegistry.Key<DamageType> SONIC_BOOM = DynamicRegistry.Key.of("minecraft:sonic_boom");
DynamicRegistry.Key<DamageType> DRY_OUT = DynamicRegistry.Key.of("minecraft:dry_out");
DynamicRegistry.Key<DamageType> ENDER_PEARL = DynamicRegistry.Key.of("minecraft:ender_pearl");
DynamicRegistry.Key<DamageType> FALL = DynamicRegistry.Key.of("minecraft:fall");
DynamicRegistry.Key<DamageType> MOB_ATTACK = DynamicRegistry.Key.of("minecraft:mob_attack");
DynamicRegistry.Key<DamageType> MOB_PROJECTILE = DynamicRegistry.Key.of("minecraft:mob_projectile");
DynamicRegistry.Key<DamageType> THROWN = DynamicRegistry.Key.of("minecraft:thrown");
DynamicRegistry.Key<DamageType> FALLING_BLOCK = DynamicRegistry.Key.of("minecraft:falling_block");
DynamicRegistry.Key<DamageType> WIND_CHARGE = DynamicRegistry.Key.of("minecraft:wind_charge");
DynamicRegistry.Key<DamageType> PLAYER_EXPLOSION = DynamicRegistry.Key.of("minecraft:player_explosion");
DynamicRegistry.Key<DamageType> UNATTRIBUTED_FIREBALL = DynamicRegistry.Key.of("minecraft:unattributed_fireball");
DynamicRegistry.Key<DamageType> IN_WALL = DynamicRegistry.Key.of("minecraft:in_wall");
DynamicRegistry.Key<DamageType> STARVE = DynamicRegistry.Key.of("minecraft:starve");
DynamicRegistry.Key<DamageType> MOB_ATTACK_NO_AGGRO = DynamicRegistry.Key.of("minecraft:mob_attack_no_aggro");
DynamicRegistry.Key<DamageType> OUTSIDE_BORDER = DynamicRegistry.Key.of("minecraft:outside_border");
DynamicRegistry.Key<DamageType> LIGHTNING_BOLT = DynamicRegistry.Key.of("minecraft:lightning_bolt");
DynamicRegistry.Key<DamageType> OUT_OF_WORLD = DynamicRegistry.Key.of("minecraft:out_of_world");
DynamicRegistry.Key<DamageType> MAGIC = DynamicRegistry.Key.of("minecraft:magic");
DynamicRegistry.Key<DamageType> EXPLOSION = DynamicRegistry.Key.of("minecraft:explosion");
DynamicRegistry.Key<DamageType> BAD_RESPAWN_POINT = DynamicRegistry.Key.of("minecraft:bad_respawn_point");
DynamicRegistry.Key<DamageType> STALAGMITE = DynamicRegistry.Key.of("minecraft:stalagmite");
DynamicRegistry.Key<DamageType> THORNS = DynamicRegistry.Key.of("minecraft:thorns");
DynamicRegistry.Key<DamageType> INDIRECT_MAGIC = DynamicRegistry.Key.of("minecraft:indirect_magic");
@ -98,6 +104,4 @@ interface DamageTypes {
DynamicRegistry.Key<DamageType> CRAMMING = DynamicRegistry.Key.of("minecraft:cramming");
DynamicRegistry.Key<DamageType> CACTUS = DynamicRegistry.Key.of("minecraft:cactus");
DynamicRegistry.Key<DamageType> GENERIC = DynamicRegistry.Key.of("minecraft:generic");
}

View File

@ -45,6 +45,10 @@ interface Blocks {
Block DARK_OAK_PLANKS = BlockImpl.get("minecraft:dark_oak_planks");
Block PALE_OAK_WOOD = BlockImpl.get("minecraft:pale_oak_wood");
Block PALE_OAK_PLANKS = BlockImpl.get("minecraft:pale_oak_planks");
Block MANGROVE_PLANKS = BlockImpl.get("minecraft:mangrove_planks");
Block BAMBOO_PLANKS = BlockImpl.get("minecraft:bamboo_planks");
@ -65,6 +69,8 @@ interface Blocks {
Block DARK_OAK_SAPLING = BlockImpl.get("minecraft:dark_oak_sapling");
Block PALE_OAK_SAPLING = BlockImpl.get("minecraft:pale_oak_sapling");
Block MANGROVE_PROPAGULE = BlockImpl.get("minecraft:mangrove_propagule");
Block BEDROCK = BlockImpl.get("minecraft:bedrock");
@ -111,6 +117,8 @@ interface Blocks {
Block DARK_OAK_LOG = BlockImpl.get("minecraft:dark_oak_log");
Block PALE_OAK_LOG = BlockImpl.get("minecraft:pale_oak_log");
Block MANGROVE_LOG = BlockImpl.get("minecraft:mangrove_log");
Block MANGROVE_ROOTS = BlockImpl.get("minecraft:mangrove_roots");
@ -131,6 +139,8 @@ interface Blocks {
Block STRIPPED_DARK_OAK_LOG = BlockImpl.get("minecraft:stripped_dark_oak_log");
Block STRIPPED_PALE_OAK_LOG = BlockImpl.get("minecraft:stripped_pale_oak_log");
Block STRIPPED_OAK_LOG = BlockImpl.get("minecraft:stripped_oak_log");
Block STRIPPED_MANGROVE_LOG = BlockImpl.get("minecraft:stripped_mangrove_log");
@ -167,6 +177,8 @@ interface Blocks {
Block STRIPPED_DARK_OAK_WOOD = BlockImpl.get("minecraft:stripped_dark_oak_wood");
Block STRIPPED_PALE_OAK_WOOD = BlockImpl.get("minecraft:stripped_pale_oak_wood");
Block STRIPPED_MANGROVE_WOOD = BlockImpl.get("minecraft:stripped_mangrove_wood");
Block OAK_LEAVES = BlockImpl.get("minecraft:oak_leaves");
@ -183,6 +195,8 @@ interface Blocks {
Block DARK_OAK_LEAVES = BlockImpl.get("minecraft:dark_oak_leaves");
Block PALE_OAK_LEAVES = BlockImpl.get("minecraft:pale_oak_leaves");
Block MANGROVE_LEAVES = BlockImpl.get("minecraft:mangrove_leaves");
Block AZALEA_LEAVES = BlockImpl.get("minecraft:azalea_leaves");
@ -357,6 +371,8 @@ interface Blocks {
Block SPAWNER = BlockImpl.get("minecraft:spawner");
Block CREAKING_HEART = BlockImpl.get("minecraft:creaking_heart");
Block OAK_STAIRS = BlockImpl.get("minecraft:oak_stairs");
Block CHEST = BlockImpl.get("minecraft:chest");
@ -391,6 +407,8 @@ interface Blocks {
Block DARK_OAK_SIGN = BlockImpl.get("minecraft:dark_oak_sign");
Block PALE_OAK_SIGN = BlockImpl.get("minecraft:pale_oak_sign");
Block MANGROVE_SIGN = BlockImpl.get("minecraft:mangrove_sign");
Block BAMBOO_SIGN = BlockImpl.get("minecraft:bamboo_sign");
@ -417,6 +435,8 @@ interface Blocks {
Block DARK_OAK_WALL_SIGN = BlockImpl.get("minecraft:dark_oak_wall_sign");
Block PALE_OAK_WALL_SIGN = BlockImpl.get("minecraft:pale_oak_wall_sign");
Block MANGROVE_WALL_SIGN = BlockImpl.get("minecraft:mangrove_wall_sign");
Block BAMBOO_WALL_SIGN = BlockImpl.get("minecraft:bamboo_wall_sign");
@ -435,6 +455,8 @@ interface Blocks {
Block DARK_OAK_HANGING_SIGN = BlockImpl.get("minecraft:dark_oak_hanging_sign");
Block PALE_OAK_HANGING_SIGN = BlockImpl.get("minecraft:pale_oak_hanging_sign");
Block CRIMSON_HANGING_SIGN = BlockImpl.get("minecraft:crimson_hanging_sign");
Block WARPED_HANGING_SIGN = BlockImpl.get("minecraft:warped_hanging_sign");
@ -457,6 +479,8 @@ interface Blocks {
Block DARK_OAK_WALL_HANGING_SIGN = BlockImpl.get("minecraft:dark_oak_wall_hanging_sign");
Block PALE_OAK_WALL_HANGING_SIGN = BlockImpl.get("minecraft:pale_oak_wall_hanging_sign");
Block MANGROVE_WALL_HANGING_SIGN = BlockImpl.get("minecraft:mangrove_wall_hanging_sign");
Block CRIMSON_WALL_HANGING_SIGN = BlockImpl.get("minecraft:crimson_wall_hanging_sign");
@ -485,6 +509,8 @@ interface Blocks {
Block DARK_OAK_PRESSURE_PLATE = BlockImpl.get("minecraft:dark_oak_pressure_plate");
Block PALE_OAK_PRESSURE_PLATE = BlockImpl.get("minecraft:pale_oak_pressure_plate");
Block MANGROVE_PRESSURE_PLATE = BlockImpl.get("minecraft:mangrove_pressure_plate");
Block BAMBOO_PRESSURE_PLATE = BlockImpl.get("minecraft:bamboo_pressure_plate");
@ -587,6 +613,8 @@ interface Blocks {
Block DARK_OAK_TRAPDOOR = BlockImpl.get("minecraft:dark_oak_trapdoor");
Block PALE_OAK_TRAPDOOR = BlockImpl.get("minecraft:pale_oak_trapdoor");
Block MANGROVE_TRAPDOOR = BlockImpl.get("minecraft:mangrove_trapdoor");
Block BAMBOO_TRAPDOOR = BlockImpl.get("minecraft:bamboo_trapdoor");
@ -733,6 +761,8 @@ interface Blocks {
Block POTTED_DARK_OAK_SAPLING = BlockImpl.get("minecraft:potted_dark_oak_sapling");
Block POTTED_PALE_OAK_SAPLING = BlockImpl.get("minecraft:potted_pale_oak_sapling");
Block POTTED_MANGROVE_PROPAGULE = BlockImpl.get("minecraft:potted_mangrove_propagule");
Block POTTED_FERN = BlockImpl.get("minecraft:potted_fern");
@ -789,6 +819,8 @@ interface Blocks {
Block DARK_OAK_BUTTON = BlockImpl.get("minecraft:dark_oak_button");
Block PALE_OAK_BUTTON = BlockImpl.get("minecraft:pale_oak_button");
Block MANGROVE_BUTTON = BlockImpl.get("minecraft:mangrove_button");
Block BAMBOO_BUTTON = BlockImpl.get("minecraft:bamboo_button");
@ -925,6 +957,8 @@ interface Blocks {
Block DARK_OAK_STAIRS = BlockImpl.get("minecraft:dark_oak_stairs");
Block PALE_OAK_STAIRS = BlockImpl.get("minecraft:pale_oak_stairs");
Block MANGROVE_STAIRS = BlockImpl.get("minecraft:mangrove_stairs");
Block BAMBOO_STAIRS = BlockImpl.get("minecraft:bamboo_stairs");
@ -1097,6 +1131,8 @@ interface Blocks {
Block DARK_OAK_SLAB = BlockImpl.get("minecraft:dark_oak_slab");
Block PALE_OAK_SLAB = BlockImpl.get("minecraft:pale_oak_slab");
Block MANGROVE_SLAB = BlockImpl.get("minecraft:mangrove_slab");
Block BAMBOO_SLAB = BlockImpl.get("minecraft:bamboo_slab");
@ -1151,6 +1187,8 @@ interface Blocks {
Block DARK_OAK_FENCE_GATE = BlockImpl.get("minecraft:dark_oak_fence_gate");
Block PALE_OAK_FENCE_GATE = BlockImpl.get("minecraft:pale_oak_fence_gate");
Block MANGROVE_FENCE_GATE = BlockImpl.get("minecraft:mangrove_fence_gate");
Block BAMBOO_FENCE_GATE = BlockImpl.get("minecraft:bamboo_fence_gate");
@ -1167,6 +1205,8 @@ interface Blocks {
Block DARK_OAK_FENCE = BlockImpl.get("minecraft:dark_oak_fence");
Block PALE_OAK_FENCE = BlockImpl.get("minecraft:pale_oak_fence");
Block MANGROVE_FENCE = BlockImpl.get("minecraft:mangrove_fence");
Block BAMBOO_FENCE = BlockImpl.get("minecraft:bamboo_fence");
@ -1183,6 +1223,8 @@ interface Blocks {
Block DARK_OAK_DOOR = BlockImpl.get("minecraft:dark_oak_door");
Block PALE_OAK_DOOR = BlockImpl.get("minecraft:pale_oak_door");
Block MANGROVE_DOOR = BlockImpl.get("minecraft:mangrove_door");
Block BAMBOO_DOOR = BlockImpl.get("minecraft:bamboo_door");
@ -2124,4 +2166,10 @@ interface Blocks {
Block VAULT = BlockImpl.get("minecraft:vault");
Block HEAVY_CORE = BlockImpl.get("minecraft:heavy_core");
Block PALE_MOSS_BLOCK = BlockImpl.get("minecraft:pale_moss_block");
Block PALE_MOSS_CARPET = BlockImpl.get("minecraft:pale_moss_carpet");
Block PALE_HANGING_MOSS = BlockImpl.get("minecraft:pale_hanging_moss");
}

View File

@ -91,6 +91,8 @@ interface Materials {
Material DARK_OAK_PLANKS = MaterialImpl.get("minecraft:dark_oak_planks");
Material PALE_OAK_PLANKS = MaterialImpl.get("minecraft:pale_oak_planks");
Material MANGROVE_PLANKS = MaterialImpl.get("minecraft:mangrove_planks");
Material BAMBOO_PLANKS = MaterialImpl.get("minecraft:bamboo_planks");
@ -115,6 +117,8 @@ interface Materials {
Material DARK_OAK_SAPLING = MaterialImpl.get("minecraft:dark_oak_sapling");
Material PALE_OAK_SAPLING = MaterialImpl.get("minecraft:pale_oak_sapling");
Material MANGROVE_PROPAGULE = MaterialImpl.get("minecraft:mangrove_propagule");
Material BEDROCK = MaterialImpl.get("minecraft:bedrock");
@ -281,6 +285,8 @@ interface Materials {
Material CHERRY_LOG = MaterialImpl.get("minecraft:cherry_log");
Material PALE_OAK_LOG = MaterialImpl.get("minecraft:pale_oak_log");
Material DARK_OAK_LOG = MaterialImpl.get("minecraft:dark_oak_log");
Material MANGROVE_LOG = MaterialImpl.get("minecraft:mangrove_log");
@ -309,6 +315,8 @@ interface Materials {
Material STRIPPED_DARK_OAK_LOG = MaterialImpl.get("minecraft:stripped_dark_oak_log");
Material STRIPPED_PALE_OAK_LOG = MaterialImpl.get("minecraft:stripped_pale_oak_log");
Material STRIPPED_MANGROVE_LOG = MaterialImpl.get("minecraft:stripped_mangrove_log");
Material STRIPPED_CRIMSON_STEM = MaterialImpl.get("minecraft:stripped_crimson_stem");
@ -329,6 +337,8 @@ interface Materials {
Material STRIPPED_DARK_OAK_WOOD = MaterialImpl.get("minecraft:stripped_dark_oak_wood");
Material STRIPPED_PALE_OAK_WOOD = MaterialImpl.get("minecraft:stripped_pale_oak_wood");
Material STRIPPED_MANGROVE_WOOD = MaterialImpl.get("minecraft:stripped_mangrove_wood");
Material STRIPPED_CRIMSON_HYPHAE = MaterialImpl.get("minecraft:stripped_crimson_hyphae");
@ -349,6 +359,8 @@ interface Materials {
Material CHERRY_WOOD = MaterialImpl.get("minecraft:cherry_wood");
Material PALE_OAK_WOOD = MaterialImpl.get("minecraft:pale_oak_wood");
Material DARK_OAK_WOOD = MaterialImpl.get("minecraft:dark_oak_wood");
Material MANGROVE_WOOD = MaterialImpl.get("minecraft:mangrove_wood");
@ -371,6 +383,8 @@ interface Materials {
Material DARK_OAK_LEAVES = MaterialImpl.get("minecraft:dark_oak_leaves");
Material PALE_OAK_LEAVES = MaterialImpl.get("minecraft:pale_oak_leaves");
Material MANGROVE_LEAVES = MaterialImpl.get("minecraft:mangrove_leaves");
Material AZALEA_LEAVES = MaterialImpl.get("minecraft:azalea_leaves");
@ -495,12 +509,18 @@ interface Materials {
Material KELP = MaterialImpl.get("minecraft:kelp");
Material MOSS_CARPET = MaterialImpl.get("minecraft:moss_carpet");
Material PINK_PETALS = MaterialImpl.get("minecraft:pink_petals");
Material MOSS_CARPET = MaterialImpl.get("minecraft:moss_carpet");
Material MOSS_BLOCK = MaterialImpl.get("minecraft:moss_block");
Material PALE_MOSS_CARPET = MaterialImpl.get("minecraft:pale_moss_carpet");
Material PALE_HANGING_MOSS = MaterialImpl.get("minecraft:pale_hanging_moss");
Material PALE_MOSS_BLOCK = MaterialImpl.get("minecraft:pale_moss_block");
Material HANGING_ROOTS = MaterialImpl.get("minecraft:hanging_roots");
Material BIG_DRIPLEAF = MaterialImpl.get("minecraft:big_dripleaf");
@ -523,6 +543,8 @@ interface Materials {
Material DARK_OAK_SLAB = MaterialImpl.get("minecraft:dark_oak_slab");
Material PALE_OAK_SLAB = MaterialImpl.get("minecraft:pale_oak_slab");
Material MANGROVE_SLAB = MaterialImpl.get("minecraft:mangrove_slab");
Material BAMBOO_SLAB = MaterialImpl.get("minecraft:bamboo_slab");
@ -603,6 +625,8 @@ interface Materials {
Material SPAWNER = MaterialImpl.get("minecraft:spawner");
Material CREAKING_HEART = MaterialImpl.get("minecraft:creaking_heart");
Material CHEST = MaterialImpl.get("minecraft:chest");
Material CRAFTING_TABLE = MaterialImpl.get("minecraft:crafting_table");
@ -641,6 +665,8 @@ interface Materials {
Material DARK_OAK_FENCE = MaterialImpl.get("minecraft:dark_oak_fence");
Material PALE_OAK_FENCE = MaterialImpl.get("minecraft:pale_oak_fence");
Material MANGROVE_FENCE = MaterialImpl.get("minecraft:mangrove_fence");
Material BAMBOO_FENCE = MaterialImpl.get("minecraft:bamboo_fence");
@ -785,6 +811,8 @@ interface Materials {
Material DARK_OAK_STAIRS = MaterialImpl.get("minecraft:dark_oak_stairs");
Material PALE_OAK_STAIRS = MaterialImpl.get("minecraft:pale_oak_stairs");
Material MANGROVE_STAIRS = MaterialImpl.get("minecraft:mangrove_stairs");
Material BAMBOO_STAIRS = MaterialImpl.get("minecraft:bamboo_stairs");
@ -1387,6 +1415,8 @@ interface Materials {
Material DARK_OAK_BUTTON = MaterialImpl.get("minecraft:dark_oak_button");
Material PALE_OAK_BUTTON = MaterialImpl.get("minecraft:pale_oak_button");
Material MANGROVE_BUTTON = MaterialImpl.get("minecraft:mangrove_button");
Material BAMBOO_BUTTON = MaterialImpl.get("minecraft:bamboo_button");
@ -1417,6 +1447,8 @@ interface Materials {
Material DARK_OAK_PRESSURE_PLATE = MaterialImpl.get("minecraft:dark_oak_pressure_plate");
Material PALE_OAK_PRESSURE_PLATE = MaterialImpl.get("minecraft:pale_oak_pressure_plate");
Material MANGROVE_PRESSURE_PLATE = MaterialImpl.get("minecraft:mangrove_pressure_plate");
Material BAMBOO_PRESSURE_PLATE = MaterialImpl.get("minecraft:bamboo_pressure_plate");
@ -1441,6 +1473,8 @@ interface Materials {
Material DARK_OAK_DOOR = MaterialImpl.get("minecraft:dark_oak_door");
Material PALE_OAK_DOOR = MaterialImpl.get("minecraft:pale_oak_door");
Material MANGROVE_DOOR = MaterialImpl.get("minecraft:mangrove_door");
Material BAMBOO_DOOR = MaterialImpl.get("minecraft:bamboo_door");
@ -1481,6 +1515,8 @@ interface Materials {
Material DARK_OAK_TRAPDOOR = MaterialImpl.get("minecraft:dark_oak_trapdoor");
Material PALE_OAK_TRAPDOOR = MaterialImpl.get("minecraft:pale_oak_trapdoor");
Material MANGROVE_TRAPDOOR = MaterialImpl.get("minecraft:mangrove_trapdoor");
Material BAMBOO_TRAPDOOR = MaterialImpl.get("minecraft:bamboo_trapdoor");
@ -1519,6 +1555,8 @@ interface Materials {
Material DARK_OAK_FENCE_GATE = MaterialImpl.get("minecraft:dark_oak_fence_gate");
Material PALE_OAK_FENCE_GATE = MaterialImpl.get("minecraft:pale_oak_fence_gate");
Material MANGROVE_FENCE_GATE = MaterialImpl.get("minecraft:mangrove_fence_gate");
Material BAMBOO_FENCE_GATE = MaterialImpl.get("minecraft:bamboo_fence_gate");
@ -1551,6 +1589,8 @@ interface Materials {
Material WARPED_FUNGUS_ON_A_STICK = MaterialImpl.get("minecraft:warped_fungus_on_a_stick");
Material PHANTOM_MEMBRANE = MaterialImpl.get("minecraft:phantom_membrane");
Material ELYTRA = MaterialImpl.get("minecraft:elytra");
Material OAK_BOAT = MaterialImpl.get("minecraft:oak_boat");
@ -1581,6 +1621,10 @@ interface Materials {
Material DARK_OAK_CHEST_BOAT = MaterialImpl.get("minecraft:dark_oak_chest_boat");
Material PALE_OAK_BOAT = MaterialImpl.get("minecraft:pale_oak_boat");
Material PALE_OAK_CHEST_BOAT = MaterialImpl.get("minecraft:pale_oak_chest_boat");
Material MANGROVE_BOAT = MaterialImpl.get("minecraft:mangrove_boat");
Material MANGROVE_CHEST_BOAT = MaterialImpl.get("minecraft:mangrove_chest_boat");
@ -1791,6 +1835,8 @@ interface Materials {
Material DARK_OAK_SIGN = MaterialImpl.get("minecraft:dark_oak_sign");
Material PALE_OAK_SIGN = MaterialImpl.get("minecraft:pale_oak_sign");
Material MANGROVE_SIGN = MaterialImpl.get("minecraft:mangrove_sign");
Material BAMBOO_SIGN = MaterialImpl.get("minecraft:bamboo_sign");
@ -1813,6 +1859,8 @@ interface Materials {
Material DARK_OAK_HANGING_SIGN = MaterialImpl.get("minecraft:dark_oak_hanging_sign");
Material PALE_OAK_HANGING_SIGN = MaterialImpl.get("minecraft:pale_oak_hanging_sign");
Material MANGROVE_HANGING_SIGN = MaterialImpl.get("minecraft:mangrove_hanging_sign");
Material BAMBOO_HANGING_SIGN = MaterialImpl.get("minecraft:bamboo_hanging_sign");
@ -1867,6 +1915,38 @@ interface Materials {
Material BUNDLE = MaterialImpl.get("minecraft:bundle");
Material WHITE_BUNDLE = MaterialImpl.get("minecraft:white_bundle");
Material ORANGE_BUNDLE = MaterialImpl.get("minecraft:orange_bundle");
Material MAGENTA_BUNDLE = MaterialImpl.get("minecraft:magenta_bundle");
Material LIGHT_BLUE_BUNDLE = MaterialImpl.get("minecraft:light_blue_bundle");
Material YELLOW_BUNDLE = MaterialImpl.get("minecraft:yellow_bundle");
Material LIME_BUNDLE = MaterialImpl.get("minecraft:lime_bundle");
Material PINK_BUNDLE = MaterialImpl.get("minecraft:pink_bundle");
Material GRAY_BUNDLE = MaterialImpl.get("minecraft:gray_bundle");
Material LIGHT_GRAY_BUNDLE = MaterialImpl.get("minecraft:light_gray_bundle");
Material CYAN_BUNDLE = MaterialImpl.get("minecraft:cyan_bundle");
Material PURPLE_BUNDLE = MaterialImpl.get("minecraft:purple_bundle");
Material BLUE_BUNDLE = MaterialImpl.get("minecraft:blue_bundle");
Material BROWN_BUNDLE = MaterialImpl.get("minecraft:brown_bundle");
Material GREEN_BUNDLE = MaterialImpl.get("minecraft:green_bundle");
Material RED_BUNDLE = MaterialImpl.get("minecraft:red_bundle");
Material BLACK_BUNDLE = MaterialImpl.get("minecraft:black_bundle");
Material FISHING_ROD = MaterialImpl.get("minecraft:fishing_rod");
Material CLOCK = MaterialImpl.get("minecraft:clock");
@ -2001,10 +2081,10 @@ interface Materials {
Material NETHER_WART = MaterialImpl.get("minecraft:nether_wart");
Material POTION = MaterialImpl.get("minecraft:potion");
Material GLASS_BOTTLE = MaterialImpl.get("minecraft:glass_bottle");
Material POTION = MaterialImpl.get("minecraft:potion");
Material SPIDER_EYE = MaterialImpl.get("minecraft:spider_eye");
Material FERMENTED_SPIDER_EYE = MaterialImpl.get("minecraft:fermented_spider_eye");
@ -2173,6 +2253,8 @@ interface Materials {
Material ZOGLIN_SPAWN_EGG = MaterialImpl.get("minecraft:zoglin_spawn_egg");
Material CREAKING_SPAWN_EGG = MaterialImpl.get("minecraft:creaking_spawn_egg");
Material ZOMBIE_SPAWN_EGG = MaterialImpl.get("minecraft:zombie_spawn_egg");
Material ZOMBIE_HORSE_SPAWN_EGG = MaterialImpl.get("minecraft:zombie_horse_spawn_egg");
@ -2191,6 +2273,8 @@ interface Materials {
Material WRITTEN_BOOK = MaterialImpl.get("minecraft:written_book");
Material BREEZE_ROD = MaterialImpl.get("minecraft:breeze_rod");
Material MACE = MaterialImpl.get("minecraft:mace");
Material ITEM_FRAME = MaterialImpl.get("minecraft:item_frame");
@ -2383,8 +2467,6 @@ interface Materials {
Material TRIDENT = MaterialImpl.get("minecraft:trident");
Material PHANTOM_MEMBRANE = MaterialImpl.get("minecraft:phantom_membrane");
Material NAUTILUS_SHELL = MaterialImpl.get("minecraft:nautilus_shell");
Material HEART_OF_THE_SEA = MaterialImpl.get("minecraft:heart_of_the_sea");
@ -2411,6 +2493,10 @@ interface Materials {
Material GUSTER_BANNER_PATTERN = MaterialImpl.get("minecraft:guster_banner_pattern");
Material FIELD_MASONED_BANNER_PATTERN = MaterialImpl.get("minecraft:field_masoned_banner_pattern");
Material BORDURE_INDENTED_BANNER_PATTERN = MaterialImpl.get("minecraft:bordure_indented_banner_pattern");
Material GOAT_HORN = MaterialImpl.get("minecraft:goat_horn");
Material COMPOSTER = MaterialImpl.get("minecraft:composter");
@ -2668,6 +2754,4 @@ interface Materials {
Material VAULT = MaterialImpl.get("minecraft:vault");
Material OMINOUS_BOTTLE = MaterialImpl.get("minecraft:ominous_bottle");
Material BREEZE_ROD = MaterialImpl.get("minecraft:breeze_rod");
}

View File

@ -0,0 +1,43 @@
package net.minestom.server.item.component;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;
/**
* AUTOGENERATED by GenericEnumGenerator
*/
enum ConsumeEffectType implements StaticProtocolObject {
APPLY_EFFECTS(NamespaceID.from("minecraft:apply_effects")),
REMOVE_EFFECTS(NamespaceID.from("minecraft:remove_effects")),
CLEAR_ALL_EFFECTS(NamespaceID.from("minecraft:clear_all_effects")),
TELEPORT_RANDOMLY(NamespaceID.from("minecraft:teleport_randomly")),
PLAY_SOUND(NamespaceID.from("minecraft:play_sound"));
public static final NetworkBuffer.Type<ConsumeEffectType> NETWORK_TYPE = NetworkBuffer.Enum(ConsumeEffectType.class);
public static final BinaryTagSerializer<ConsumeEffectType> NBT_TYPE = BinaryTagSerializer.fromEnumKeyed(ConsumeEffectType.class);
private final NamespaceID namespace;
ConsumeEffectType(@NotNull NamespaceID namespace) {
this.namespace = namespace;
}
@NotNull
@Override
public NamespaceID namespace() {
return this.namespace;
}
@Override
public int id() {
return this.ordinal();
}
}

View File

@ -96,6 +96,8 @@ interface Particles {
Particle.Vibration VIBRATION = (Particle.Vibration) ParticleImpl.get("minecraft:vibration");
Particle.Trail TRAIL = (Particle.Trail) ParticleImpl.get("minecraft:trail");
Particle ITEM_SLIME = ParticleImpl.get("minecraft:item_slime");
Particle ITEM_COBWEB = ParticleImpl.get("minecraft:item_cobweb");
@ -221,4 +223,6 @@ interface Particles {
Particle RAID_OMEN = ParticleImpl.get("minecraft:raid_omen");
Particle TRIAL_OMEN = ParticleImpl.get("minecraft:trial_omen");
Particle.BlockCrumble BLOCK_CRUMBLE = (Particle.BlockCrumble) ParticleImpl.get("minecraft:block_crumble");
}

View File

@ -0,0 +1,59 @@
package net.minestom.server.recipe;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;
/**
* AUTOGENERATED by GenericEnumGenerator
*/
public enum RecipeBookCategory implements StaticProtocolObject {
CRAFTING_BUILDING_BLOCKS(NamespaceID.from("minecraft:crafting_building_blocks")),
CRAFTING_REDSTONE(NamespaceID.from("minecraft:crafting_redstone")),
CRAFTING_EQUIPMENT(NamespaceID.from("minecraft:crafting_equipment")),
CRAFTING_MISC(NamespaceID.from("minecraft:crafting_misc")),
FURNACE_FOOD(NamespaceID.from("minecraft:furnace_food")),
FURNACE_BLOCKS(NamespaceID.from("minecraft:furnace_blocks")),
FURNACE_MISC(NamespaceID.from("minecraft:furnace_misc")),
BLAST_FURNACE_BLOCKS(NamespaceID.from("minecraft:blast_furnace_blocks")),
BLAST_FURNACE_MISC(NamespaceID.from("minecraft:blast_furnace_misc")),
SMOKER_FOOD(NamespaceID.from("minecraft:smoker_food")),
STONECUTTER(NamespaceID.from("minecraft:stonecutter")),
SMITHING(NamespaceID.from("minecraft:smithing")),
CAMPFIRE(NamespaceID.from("minecraft:campfire"));
public static final NetworkBuffer.Type<RecipeBookCategory> NETWORK_TYPE = NetworkBuffer.Enum(RecipeBookCategory.class);
public static final BinaryTagSerializer<RecipeBookCategory> NBT_TYPE = BinaryTagSerializer.fromEnumKeyed(RecipeBookCategory.class);
private final NamespaceID namespace;
RecipeBookCategory(@NotNull NamespaceID namespace) {
this.namespace = namespace;
}
@NotNull
@Override
public NamespaceID namespace() {
return this.namespace;
}
@Override
public int id() {
return this.ordinal();
}
}

View File

@ -3,41 +3,14 @@ package net.minestom.server.recipe;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;
/**
* AUTOGENERATED by RecipeTypeGenerator
*/
public enum RecipeType implements StaticProtocolObject {
SHAPED(NamespaceID.from("minecraft:crafting_shaped")),
SHAPELESS(NamespaceID.from("minecraft:crafting_shapeless")),
SPECIAL_ARMORDYE(NamespaceID.from("minecraft:crafting_special_armordye")),
SPECIAL_BOOKCLONING(NamespaceID.from("minecraft:crafting_special_bookcloning")),
SPECIAL_MAPCLONING(NamespaceID.from("minecraft:crafting_special_mapcloning")),
SPECIAL_MAPEXTENDING(NamespaceID.from("minecraft:crafting_special_mapextending")),
SPECIAL_FIREWORK_ROCKET(NamespaceID.from("minecraft:crafting_special_firework_rocket")),
SPECIAL_FIREWORK_STAR(NamespaceID.from("minecraft:crafting_special_firework_star")),
SPECIAL_FIREWORK_STAR_FADE(NamespaceID.from("minecraft:crafting_special_firework_star_fade")),
SPECIAL_TIPPEDARROW(NamespaceID.from("minecraft:crafting_special_tippedarrow")),
SPECIAL_BANNERDUPLICATE(NamespaceID.from("minecraft:crafting_special_bannerduplicate")),
SPECIAL_SHIELDDECORATION(NamespaceID.from("minecraft:crafting_special_shielddecoration")),
SPECIAL_SHULKERBOXCOLORING(NamespaceID.from("minecraft:crafting_special_shulkerboxcoloring")),
SPECIAL_SUSPICIOUSSTEW(NamespaceID.from("minecraft:crafting_special_suspiciousstew")),
SPECIAL_REPAIRITEM(NamespaceID.from("minecraft:crafting_special_repairitem")),
CRAFTING(NamespaceID.from("minecraft:crafting")),
SMELTING(NamespaceID.from("minecraft:smelting")),
@ -49,14 +22,12 @@ public enum RecipeType implements StaticProtocolObject {
STONECUTTING(NamespaceID.from("minecraft:stonecutting")),
SMITHING_TRANSFORM(NamespaceID.from("minecraft:smithing_transform")),
SMITHING_TRIM(NamespaceID.from("minecraft:smithing_trim")),
DECORATED_POT(NamespaceID.from("minecraft:crafting_decorated_pot"));
SMITHING(NamespaceID.from("minecraft:smithing"));
public static final NetworkBuffer.Type<RecipeType> NETWORK_TYPE = NetworkBuffer.Enum(RecipeType.class);
public static final BinaryTagSerializer<RecipeType> NBT_TYPE = BinaryTagSerializer.fromEnumKeyed(RecipeType.class);
private final NamespaceID namespace;
RecipeType(@NotNull NamespaceID namespace) {

View File

@ -0,0 +1,43 @@
package net.minestom.server.recipe.display;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;
/**
* AUTOGENERATED by GenericEnumGenerator
*/
public enum RecipeDisplayType implements StaticProtocolObject {
CRAFTING_SHAPELESS(NamespaceID.from("minecraft:crafting_shapeless")),
CRAFTING_SHAPED(NamespaceID.from("minecraft:crafting_shaped")),
FURNACE(NamespaceID.from("minecraft:furnace")),
STONECUTTER(NamespaceID.from("minecraft:stonecutter")),
SMITHING(NamespaceID.from("minecraft:smithing"));
public static final NetworkBuffer.Type<RecipeDisplayType> NETWORK_TYPE = NetworkBuffer.Enum(RecipeDisplayType.class);
public static final BinaryTagSerializer<RecipeDisplayType> NBT_TYPE = BinaryTagSerializer.fromEnumKeyed(RecipeDisplayType.class);
private final NamespaceID namespace;
RecipeDisplayType(@NotNull NamespaceID namespace) {
this.namespace = namespace;
}
@NotNull
@Override
public NamespaceID namespace() {
return this.namespace;
}
@Override
public int id() {
return this.ordinal();
}
}

View File

@ -0,0 +1,49 @@
package net.minestom.server.recipe.display;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import org.jetbrains.annotations.NotNull;
/**
* AUTOGENERATED by GenericEnumGenerator
*/
public enum SlotDisplayType implements StaticProtocolObject {
EMPTY(NamespaceID.from("minecraft:empty")),
ANY_FUEL(NamespaceID.from("minecraft:any_fuel")),
ITEM(NamespaceID.from("minecraft:item")),
ITEM_STACK(NamespaceID.from("minecraft:item_stack")),
TAG(NamespaceID.from("minecraft:tag")),
SMITHING_TRIM(NamespaceID.from("minecraft:smithing_trim")),
WITH_REMAINDER(NamespaceID.from("minecraft:with_remainder")),
COMPOSITE(NamespaceID.from("minecraft:composite"));
public static final NetworkBuffer.Type<SlotDisplayType> NETWORK_TYPE = NetworkBuffer.Enum(SlotDisplayType.class);
public static final BinaryTagSerializer<SlotDisplayType> NBT_TYPE = BinaryTagSerializer.fromEnumKeyed(SlotDisplayType.class);
private final NamespaceID namespace;
SlotDisplayType(@NotNull NamespaceID namespace) {
this.namespace = namespace;
}
@NotNull
@Override
public NamespaceID namespace() {
return this.namespace;
}
@Override
public int id() {
return this.ordinal();
}
}

View File

@ -425,6 +425,8 @@ interface SoundEvents {
SoundEvent BLOCK_BUBBLE_COLUMN_WHIRLPOOL_INSIDE = BuiltinSoundEvent.get("minecraft:block.bubble_column.whirlpool_inside");
SoundEvent UI_HUD_BUBBLE_POP = BuiltinSoundEvent.get("minecraft:ui.hud.bubble_pop");
SoundEvent ITEM_BUCKET_EMPTY = BuiltinSoundEvent.get("minecraft:item.bucket.empty");
SoundEvent ITEM_BUCKET_EMPTY_AXOLOTL = BuiltinSoundEvent.get("minecraft:item.bucket.empty_axolotl");
@ -453,6 +455,8 @@ interface SoundEvents {
SoundEvent ITEM_BUNDLE_INSERT = BuiltinSoundEvent.get("minecraft:item.bundle.insert");
SoundEvent ITEM_BUNDLE_INSERT_FAIL = BuiltinSoundEvent.get("minecraft:item.bundle.insert_fail");
SoundEvent ITEM_BUNDLE_REMOVE_ONE = BuiltinSoundEvent.get("minecraft:item.bundle.remove_one");
SoundEvent BLOCK_CAKE_ADD_CANDLE = BuiltinSoundEvent.get("minecraft:block.cake.add_candle");
@ -749,6 +753,42 @@ interface SoundEvents {
SoundEvent BLOCK_CRAFTER_FAIL = BuiltinSoundEvent.get("minecraft:block.crafter.fail");
SoundEvent ENTITY_CREAKING_AMBIENT = BuiltinSoundEvent.get("minecraft:entity.creaking.ambient");
SoundEvent ENTITY_CREAKING_ACTIVATE = BuiltinSoundEvent.get("minecraft:entity.creaking.activate");
SoundEvent ENTITY_CREAKING_DEACTIVATE = BuiltinSoundEvent.get("minecraft:entity.creaking.deactivate");
SoundEvent ENTITY_CREAKING_ATTACK = BuiltinSoundEvent.get("minecraft:entity.creaking.attack");
SoundEvent ENTITY_CREAKING_DEATH = BuiltinSoundEvent.get("minecraft:entity.creaking.death");
SoundEvent ENTITY_CREAKING_STEP = BuiltinSoundEvent.get("minecraft:entity.creaking.step");
SoundEvent ENTITY_CREAKING_FREEZE = BuiltinSoundEvent.get("minecraft:entity.creaking.freeze");
SoundEvent ENTITY_CREAKING_UNFREEZE = BuiltinSoundEvent.get("minecraft:entity.creaking.unfreeze");
SoundEvent ENTITY_CREAKING_SPAWN = BuiltinSoundEvent.get("minecraft:entity.creaking.spawn");
SoundEvent ENTITY_CREAKING_SWAY = BuiltinSoundEvent.get("minecraft:entity.creaking.sway");
SoundEvent BLOCK_CREAKING_HEART_BREAK = BuiltinSoundEvent.get("minecraft:block.creaking_heart.break");
SoundEvent BLOCK_CREAKING_HEART_FALL = BuiltinSoundEvent.get("minecraft:block.creaking_heart.fall");
SoundEvent BLOCK_CREAKING_HEART_HIT = BuiltinSoundEvent.get("minecraft:block.creaking_heart.hit");
SoundEvent BLOCK_CREAKING_HEART_HURT = BuiltinSoundEvent.get("minecraft:block.creaking_heart.hurt");
SoundEvent BLOCK_CREAKING_HEART_PLACE = BuiltinSoundEvent.get("minecraft:block.creaking_heart.place");
SoundEvent BLOCK_CREAKING_HEART_STEP = BuiltinSoundEvent.get("minecraft:block.creaking_heart.step");
SoundEvent BLOCK_CREAKING_HEART_IDLE = BuiltinSoundEvent.get("minecraft:block.creaking_heart.idle");
SoundEvent BLOCK_CREAKING_HEART_SPAWN = BuiltinSoundEvent.get("minecraft:block.creaking_heart.spawn");
SoundEvent ENTITY_CREEPER_DEATH = BuiltinSoundEvent.get("minecraft:entity.creeper.death");
SoundEvent ENTITY_CREEPER_HURT = BuiltinSoundEvent.get("minecraft:entity.creeper.hurt");
@ -1239,8 +1279,6 @@ interface SoundEvents {
SoundEvent ENTITY_GOAT_HORN_BREAK = BuiltinSoundEvent.get("minecraft:entity.goat.horn_break");
SoundEvent ITEM_GOAT_HORN_PLAY = BuiltinSoundEvent.get("minecraft:item.goat_horn.play");
SoundEvent ENTITY_GOAT_SCREAMING_AMBIENT = BuiltinSoundEvent.get("minecraft:entity.goat.screaming.ambient");
SoundEvent ENTITY_GOAT_SCREAMING_DEATH = BuiltinSoundEvent.get("minecraft:entity.goat.screaming.death");
@ -1257,8 +1295,6 @@ interface SoundEvents {
SoundEvent ENTITY_GOAT_SCREAMING_RAM_IMPACT = BuiltinSoundEvent.get("minecraft:entity.goat.screaming.ram_impact");
SoundEvent ENTITY_GOAT_SCREAMING_HORN_BREAK = BuiltinSoundEvent.get("minecraft:entity.goat.screaming.horn_break");
SoundEvent ENTITY_GOAT_STEP = BuiltinSoundEvent.get("minecraft:entity.goat.step");
SoundEvent BLOCK_GRASS_BREAK = BuiltinSoundEvent.get("minecraft:block.grass.break");
@ -2033,6 +2069,8 @@ interface SoundEvents {
SoundEvent ENTITY_PAINTING_PLACE = BuiltinSoundEvent.get("minecraft:entity.painting.place");
SoundEvent BLOCK_PALE_HANGING_MOSS_IDLE = BuiltinSoundEvent.get("minecraft:block.pale_hanging_moss.idle");
SoundEvent ENTITY_PANDA_PRE_SNEEZE = BuiltinSoundEvent.get("minecraft:entity.panda.pre_sneeze");
SoundEvent ENTITY_PANDA_SNEEZE = BuiltinSoundEvent.get("minecraft:entity.panda.sneeze");
@ -2071,6 +2109,8 @@ interface SoundEvents {
SoundEvent ENTITY_PARROT_IMITATE_BREEZE = BuiltinSoundEvent.get("minecraft:entity.parrot.imitate.breeze");
SoundEvent ENTITY_PARROT_IMITATE_CREAKING = BuiltinSoundEvent.get("minecraft:entity.parrot.imitate.creaking");
SoundEvent ENTITY_PARROT_IMITATE_CREEPER = BuiltinSoundEvent.get("minecraft:entity.parrot.imitate.creeper");
SoundEvent ENTITY_PARROT_IMITATE_DROWNED = BuiltinSoundEvent.get("minecraft:entity.parrot.imitate.drowned");
@ -2599,6 +2639,16 @@ interface SoundEvents {
SoundEvent PARTICLE_SOUL_ESCAPE = BuiltinSoundEvent.get("minecraft:particle.soul_escape");
SoundEvent BLOCK_SPAWNER_BREAK = BuiltinSoundEvent.get("minecraft:block.spawner.break");
SoundEvent BLOCK_SPAWNER_FALL = BuiltinSoundEvent.get("minecraft:block.spawner.fall");
SoundEvent BLOCK_SPAWNER_HIT = BuiltinSoundEvent.get("minecraft:block.spawner.hit");
SoundEvent BLOCK_SPAWNER_PLACE = BuiltinSoundEvent.get("minecraft:block.spawner.place");
SoundEvent BLOCK_SPAWNER_STEP = BuiltinSoundEvent.get("minecraft:block.spawner.step");
SoundEvent BLOCK_SPORE_BLOSSOM_BREAK = BuiltinSoundEvent.get("minecraft:block.spore_blossom.break");
SoundEvent BLOCK_SPORE_BLOSSOM_FALL = BuiltinSoundEvent.get("minecraft:block.spore_blossom.fall");

View File

@ -21,7 +21,8 @@ import net.minestom.server.listener.manager.PacketListenerManager;
import net.minestom.server.message.ChatType;
import net.minestom.server.monitoring.BenchmarkManager;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.network.PacketProcessor;
import net.minestom.server.network.packet.PacketParser;
import net.minestom.server.network.packet.client.ClientPacket;
import net.minestom.server.network.packet.server.common.PluginMessagePacket;
import net.minestom.server.network.packet.server.play.ServerDifficultyPacket;
import net.minestom.server.network.socket.Server;
@ -30,7 +31,7 @@ import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.scoreboard.TeamManager;
import net.minestom.server.thread.TickSchedulerThread;
import net.minestom.server.timer.SchedulerManager;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.PacketSendingUtils;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import net.minestom.server.utils.validate.Check;
import net.minestom.server.world.Difficulty;
@ -40,7 +41,6 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnknownNullability;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
@ -80,13 +80,8 @@ public final class MinecraftServer implements MinecraftConstants {
@ApiStatus.Internal
public static ServerProcess updateProcess() {
ServerProcess process;
try {
process = new ServerProcessImpl();
serverProcess = process;
} catch (IOException e) {
throw new RuntimeException(e);
}
ServerProcess process = new ServerProcessImpl();
serverProcess = process;
return process;
}
@ -108,7 +103,7 @@ public final class MinecraftServer implements MinecraftConstants {
*/
public static void setBrandName(@NotNull String brandName) {
MinecraftServer.brandName = brandName;
PacketUtils.broadcastPlayPacket(PluginMessagePacket.getBrandPacket());
PacketSendingUtils.broadcastPlayPacket(PluginMessagePacket.brandPacket(brandName));
}
/**
@ -128,7 +123,7 @@ public final class MinecraftServer implements MinecraftConstants {
*/
public static void setDifficulty(@NotNull Difficulty difficulty) {
MinecraftServer.difficulty = difficulty;
PacketUtils.broadcastPlayPacket(new ServerDifficultyPacket(difficulty, true));
PacketSendingUtils.broadcastPlayPacket(new ServerDifficultyPacket(difficulty, true));
}
public static @UnknownNullability ServerProcess process() {
@ -188,8 +183,8 @@ public final class MinecraftServer implements MinecraftConstants {
return serverProcess.bossBar();
}
public static @NotNull PacketProcessor getPacketProcessor() {
return serverProcess.packetProcessor();
public static @NotNull PacketParser<ClientPacket> getPacketParser() {
return serverProcess.packetParser();
}
public static boolean isStarted() {

View File

@ -18,13 +18,7 @@ public final class ServerFlag {
public static final int CHUNK_VIEW_DISTANCE = intProperty("minestom.chunk-view-distance", 8);
public static final int ENTITY_VIEW_DISTANCE = intProperty("minestom.entity-view-distance", 5);
public static final int ENTITY_SYNCHRONIZATION_TICKS = intProperty("minestom.entity-synchronization-ticks", 20);
public static final int WORKER_COUNT = intProperty("minestom.workers", Runtime.getRuntime().availableProcessors());
public static final int DISPATCHER_THREADS = intProperty("minestom.dispatcher-threads", 1);
public static final int MAX_PACKET_SIZE = intProperty("minestom.max-packet-size", 2_097_151); // 3 bytes var-int
public static final int SOCKET_SEND_BUFFER_SIZE = intProperty("minestom.send-buffer-size", 262_143);
public static final int SOCKET_RECEIVE_BUFFER_SIZE = intProperty("minestom.receive-buffer-size", 32_767);
public static final boolean SOCKET_NO_DELAY = booleanProperty("minestom.tcp-no-delay", true);
public static final int POOLED_BUFFER_SIZE = intProperty("minestom.pooled-buffer-size", 262_143);
public static final int SEND_LIGHT_AFTER_BLOCK_PLACEMENT_DELAY = intProperty("minestom.send-light-after-block-placement-delay", 100);
public static final long LOGIN_PLUGIN_MESSAGE_TIMEOUT = longProperty("minestom.login-plugin-message-timeout", 5_000);
@ -34,6 +28,15 @@ public final class ServerFlag {
public static final long KEEP_ALIVE_DELAY = longProperty("minestom.keep-alive-delay", 10_000);
public static final long KEEP_ALIVE_KICK = longProperty("minestom.keep-alive-kick", 15_000);
// Network buffers
public static final int MAX_PACKET_SIZE = intProperty("minestom.max-packet-size", 2_097_151); // 3 bytes var-int
public static final int MAX_PACKET_SIZE_PRE_AUTH = intProperty("minestom.max-packet-size-pre-auth", 8_192);
public static final int SOCKET_SEND_BUFFER_SIZE = intProperty("minestom.send-buffer-size", 262_143);
public static final int SOCKET_RECEIVE_BUFFER_SIZE = intProperty("minestom.receive-buffer-size", 32_767);
public static final boolean SOCKET_NO_DELAY = booleanProperty("minestom.tcp-no-delay", true);
public static final int SOCKET_TIMEOUT = intProperty("minestom.socket-timeout", 15_000);
public static final int POOLED_BUFFER_SIZE = intProperty("minestom.pooled-buffer-size", 16_383);
// Chunk update
public static final float MIN_CHUNKS_PER_TICK = floatProperty("minestom.chunk-queue.min-per-tick", 0.01f);
public static final float MAX_CHUNKS_PER_TICK = floatProperty("minestom.chunk-queue.max-per-tick", 64.0f);
@ -50,6 +53,7 @@ public final class ServerFlag {
// Online Mode
public static final @NotNull String AUTH_URL = stringProperty("minestom.auth.url", "https://sessionserver.mojang.com/session/minecraft/hasJoined");
public static final boolean AUTH_PREVENT_PROXY_CONNECTIONS = booleanProperty("minestom.auth.prevent-proxy-connections", false);
// World
public static final int WORLD_BORDER_SIZE = intProperty("minestom.world-border-size", 29999984);

View File

@ -13,7 +13,8 @@ import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.listener.manager.PacketListenerManager;
import net.minestom.server.monitoring.BenchmarkManager;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.network.PacketProcessor;
import net.minestom.server.network.packet.PacketParser;
import net.minestom.server.network.packet.client.ClientPacket;
import net.minestom.server.network.socket.Server;
import net.minestom.server.recipe.RecipeManager;
import net.minestom.server.registry.Registries;
@ -99,11 +100,11 @@ public interface ServerProcess extends Registries, Snapshotable {
@NotNull PacketListenerManager packetListener();
/**
* Gets the object handling the client packets processing.
* Gets the object handling the client packets parsing.
* <p>
* Can be used if you want to convert a buffer to a client packet object.
*/
@NotNull PacketProcessor packetProcessor();
@NotNull PacketParser<ClientPacket> packetParser();
/**
* Exposed socket server.

View File

@ -27,7 +27,9 @@ import net.minestom.server.message.ChatType;
import net.minestom.server.monitoring.BenchmarkManager;
import net.minestom.server.monitoring.TickMonitor;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.network.PacketProcessor;
import net.minestom.server.network.packet.PacketParser;
import net.minestom.server.network.packet.PacketVanilla;
import net.minestom.server.network.packet.client.ClientPacket;
import net.minestom.server.network.socket.Server;
import net.minestom.server.recipe.RecipeManager;
import net.minestom.server.registry.DynamicRegistry;
@ -37,7 +39,7 @@ import net.minestom.server.thread.Acquirable;
import net.minestom.server.thread.ThreadDispatcher;
import net.minestom.server.thread.ThreadProvider;
import net.minestom.server.timer.SchedulerManager;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.PacketViewableUtils;
import net.minestom.server.utils.collection.MappedCollection;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import net.minestom.server.world.DimensionType;
@ -77,7 +79,7 @@ final class ServerProcessImpl implements ServerProcess {
private final ConnectionManager connection;
private final PacketListenerManager packetListener;
private final PacketProcessor packetProcessor;
private final PacketParser<ClientPacket> packetParser;
private final InstanceManager instance;
private final BlockManager block;
private final CommandManager command;
@ -98,7 +100,7 @@ final class ServerProcessImpl implements ServerProcess {
private final AtomicBoolean started = new AtomicBoolean();
private final AtomicBoolean stopped = new AtomicBoolean();
public ServerProcessImpl() throws IOException {
public ServerProcessImpl() {
this.exception = new ExceptionManager();
// The order of initialization here is relevant, we must load the enchantment util registries before the vanilla data is loaded.
@ -122,7 +124,7 @@ final class ServerProcessImpl implements ServerProcess {
this.connection = new ConnectionManager();
this.packetListener = new PacketListenerManager();
this.packetProcessor = new PacketProcessor(packetListener);
this.packetParser = PacketVanilla.CLIENT_PACKET_PARSER;
this.instance = new InstanceManager(this);
this.block = new BlockManager();
this.command = new CommandManager();
@ -135,7 +137,7 @@ final class ServerProcessImpl implements ServerProcess {
this.bossBar = new BossBarManager();
this.tag = new TagManager();
this.server = new Server(packetProcessor);
this.server = new Server(packetParser);
this.dispatcher = ThreadDispatcher.of(ThreadProvider.counter(), ServerFlag.DISPATCHER_THREADS);
this.ticker = new TickerImpl();
@ -287,8 +289,8 @@ final class ServerProcessImpl implements ServerProcess {
}
@Override
public @NotNull PacketProcessor packetProcessor() {
return packetProcessor;
public @NotNull PacketParser<ClientPacket> packetParser() {
return packetParser;
}
@Override
@ -379,10 +381,7 @@ final class ServerProcessImpl implements ServerProcess {
scheduler().processTickEnd();
// Flush all waiting packets
PacketUtils.flush();
// Server connection tick
server().tick();
PacketViewableUtils.flush();
// Monitoring
{

View File

@ -5,7 +5,7 @@ import net.minestom.server.adventure.audience.PacketGroupingAudience;
import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.SendablePacket;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.PacketSendingUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@ -60,7 +60,7 @@ public interface Viewable {
*/
default void sendPacketToViewers(@NotNull SendablePacket packet) {
if (packet instanceof ServerPacket serverPacket) {
PacketUtils.sendGroupedPacket(getViewers(), serverPacket);
PacketSendingUtils.sendGroupedPacket(getViewers(), serverPacket);
} else {
getViewers().forEach(player -> player.sendPacket(packet));
}

View File

@ -0,0 +1,58 @@
package net.minestom.server.advancements;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
import java.util.List;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Represents a toast which can be sent to the player using {@link net.minestom.server.entity.Player#sendNotification(Notification)}.
*/
public record Notification(@NotNull Component title, @NotNull FrameType frameType, @NotNull ItemStack icon) {
private static final String IDENTIFIER = "minestom:notification";
public Notification(@NotNull Component title, @NotNull FrameType frameType, @NotNull Material icon) {
this(title, frameType, ItemStack.of(icon));
}
@ApiStatus.Internal
public @NotNull AdvancementsPacket buildAddPacket() {
// For an advancement to be shown, it must have all of its criteria achieved (progress 100%)
// Create a criteria that we can set to 100% achieved.
final var displayData = new AdvancementsPacket.DisplayData(
title, Component.text("Articdive was here. #Minestom"),
icon, frameType,
0x6, null, 0f, 0f);
final var criteria = new AdvancementsPacket.Criteria("minestom:some_criteria",
new AdvancementsPacket.CriterionProgress(System.currentTimeMillis()));
final var advancement = new AdvancementsPacket.Advancement(null, displayData,
List.of(new AdvancementsPacket.Requirement(List.of(criteria.criterionIdentifier()))),
false);
final var mapping = new AdvancementsPacket.AdvancementMapping(IDENTIFIER, advancement);
final var progressMapping = new AdvancementsPacket.ProgressMapping(IDENTIFIER,
new AdvancementsPacket.AdvancementProgress(List.of(criteria)));
return new AdvancementsPacket(
false,
List.of(mapping),
List.of(),
List.of(progressMapping));
}
@ApiStatus.Internal
public @NotNull AdvancementsPacket buildRemovePacket() {
return new AdvancementsPacket(
false,
List.of(),
List.of(IDENTIFIER),
List.of());
}
}

View File

@ -1,26 +0,0 @@
package net.minestom.server.advancements.notifications;
import net.kyori.adventure.text.Component;
import net.minestom.server.advancements.FrameType;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
/**
* Represents a message which can be sent using the {@link NotificationCenter}.
*/
public record Notification(@NotNull Component title, @NotNull FrameType frameType, @NotNull ItemStack icon) {
public Notification(@NotNull Component title, @NotNull FrameType frameType, @NotNull Material icon) {
this(title, frameType, ItemStack.of(icon));
}
@Deprecated
public @NotNull Component getTitle() {
return title;
}
@Deprecated
public @NotNull FrameType getFrameType() {
return frameType;
}
}

View File

@ -1,77 +0,0 @@
package net.minestom.server.advancements.notifications;
import net.kyori.adventure.text.Component;
import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
/**
* Used to send one or multiples {@link Notification}.
* <p>
* Works by sending a completed advancement and remove it immediately.
* <p>
* You can simply create a {@link Notification} object and call {@link #send(Notification, Player)}.
*/
public final class NotificationCenter {
private static final String IDENTIFIER = "minestom:notification";
private static final AdvancementsPacket REMOVE_PACKET = new AdvancementsPacket(false, List.of(), List.of(IDENTIFIER), List.of());
/**
* Can't create an instance, use the static methods instead.
*/
private NotificationCenter() {
}
/**
* Send a {@link Notification} to one player.
*
* @param notification the {@link Notification} to send
* @param player the player to send the notification to
*/
public static void send(@NotNull Notification notification, @NotNull Player player) {
player.sendPacket(createPacket(notification));
player.sendPacket(REMOVE_PACKET);
}
/**
* Send a {@link Notification} to a collection of players.
*
* @param notification the {@link Notification} to send
* @param players the collection of players to send the notification to
*/
public static void send(@NotNull Notification notification, @NotNull Collection<Player> players) {
// Can't use PacketWriterUtils because we need the packets to come in the correct order
players.forEach(player -> send(notification, player));
}
/**
* Create the {@link AdvancementsPacket} responsible for showing the Toast to players
*
* @param notification the notification
* @return the packet used to show the Toast
*/
private static AdvancementsPacket createPacket(Notification notification) {
// For An advancement to be shown, it must have all of its criteria achieved (progress 100%)
// Create a Criteria that we can set to 100% achieved.
final var displayData = new AdvancementsPacket.DisplayData(
notification.title(), Component.text("Articdive was here. #Minestom"),
notification.icon(), notification.frameType(),
0x6, null, 0f, 0f);
final var criteria = new AdvancementsPacket.Criteria("minestom:some_criteria",
new AdvancementsPacket.CriterionProgress(System.currentTimeMillis()));
final var advancement = new AdvancementsPacket.Advancement(null, displayData,
List.of(new AdvancementsPacket.Requirement(List.of(criteria.criterionIdentifier()))),
false);
final var mapping = new AdvancementsPacket.AdvancementMapping(IDENTIFIER, advancement);
final var progressMapping = new AdvancementsPacket.ProgressMapping(IDENTIFIER,
new AdvancementsPacket.AdvancementProgress(List.of(criteria)));
return new AdvancementsPacket(false, List.of(mapping), List.of(), List.of(progressMapping));
}
}

View File

@ -1,37 +0,0 @@
package net.minestom.server.adventure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
/**
* Represents something which can have a locale.
*/
public interface Localizable {
/**
* Gets a localizable that returns {@code null} for all calls to {@link #getLocale()}.
*
* @return the empty localizable
*/
static @NotNull Localizable empty() {
return MinestomAdventure.NULL_LOCALIZABLE;
}
/**
* Gets the locale.
*
* @return the locale, or {@code null} if they do not have a locale set
*/
@Nullable Locale getLocale();
/**
* Sets the locale. This can be set to {@code null} to remove a locale registration.
*
* @param locale the new locale
*/
default void setLocale(@Nullable Locale locale) {
throw new UnsupportedOperationException("You cannot set the locale for this object!");
}
}

View File

@ -30,8 +30,6 @@ public final class MinestomAdventure {
// todo: Need to properly add a translator interface so it can check for presence of a key for the flattener.
public static BiFunction<Component, Locale, Component> COMPONENT_TRANSLATOR = GlobalTranslator::render;
static final Localizable NULL_LOCALIZABLE = () -> null;
private static Locale defaultLocale = Locale.getDefault();
private MinestomAdventure() {

View File

@ -10,6 +10,7 @@ import net.kyori.adventure.sound.SoundStop;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.TitlePart;
import net.minestom.server.MinecraftServer;
import net.minestom.server.advancements.Notification;
import net.minestom.server.adventure.AdventurePacketConvertor;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Player;
@ -19,7 +20,7 @@ import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.play.ActionBarPacket;
import net.minestom.server.network.packet.server.play.ClearTitlesPacket;
import net.minestom.server.network.packet.server.play.PlayerListHeaderAndFooterPacket;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.PacketSendingUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@ -28,7 +29,6 @@ import java.util.Collection;
* An audience implementation that sends grouped packets if possible.
*/
public interface PacketGroupingAudience extends ForwardingAudience {
/**
* Creates a packet grouping audience that copies an iterable of players. The
* underlying collection is not copied, so changes to the collection will be
@ -54,7 +54,7 @@ public interface PacketGroupingAudience extends ForwardingAudience {
* @param packet the packet to broadcast
*/
default void sendGroupedPacket(@NotNull ServerPacket packet) {
PacketUtils.sendGroupedPacket(getPlayers(), packet);
PacketSendingUtils.sendGroupedPacket(getPlayers(), packet);
}
@Deprecated
@ -129,6 +129,15 @@ public interface PacketGroupingAudience extends ForwardingAudience {
sendGroupedPacket(AdventurePacketConvertor.createSoundStopPacket(stop));
}
/**
* Send a {@link Notification} to the audience.
* @param notification the {@link Notification} to send
*/
default void sendNotification(@NotNull Notification notification) {
sendGroupedPacket(notification.buildAddPacket());
sendGroupedPacket(notification.buildRemovePacket());
}
@Override
default @NotNull Iterable<? extends Audience> audiences() {
return this.getPlayers();

View File

@ -3,7 +3,7 @@ package net.minestom.server.adventure.bossbar;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.PacketSendingUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
@ -29,33 +29,32 @@ class BossBarListener implements BossBar.Listener {
@Override
public void bossBarNameChanged(@NotNull BossBar bar, @NotNull Component oldName, @NotNull Component newName) {
this.doIfRegistered(bar, holder -> PacketUtils.sendGroupedPacket(holder.players, holder.createTitleUpdate(newName)));
this.doIfRegistered(bar, holder -> PacketSendingUtils.sendGroupedPacket(holder.players, holder.createTitleUpdate(newName)));
}
@Override
public void bossBarProgressChanged(@NotNull BossBar bar, float oldProgress, float newProgress) {
this.doIfRegistered(bar, holder -> PacketUtils.sendGroupedPacket(holder.players, holder.createPercentUpdate(newProgress)));
this.doIfRegistered(bar, holder -> PacketSendingUtils.sendGroupedPacket(holder.players, holder.createPercentUpdate(newProgress)));
}
@Override
public void bossBarColorChanged(@NotNull BossBar bar, @NotNull BossBar.Color oldColor, @NotNull BossBar.Color newColor) {
this.doIfRegistered(bar, holder -> PacketUtils.sendGroupedPacket(holder.players, holder.createColorUpdate(newColor)));
this.doIfRegistered(bar, holder -> PacketSendingUtils.sendGroupedPacket(holder.players, holder.createColorUpdate(newColor)));
}
@Override
public void bossBarOverlayChanged(@NotNull BossBar bar, BossBar.@NotNull Overlay oldOverlay, BossBar.@NotNull Overlay newOverlay) {
this.doIfRegistered(bar, holder -> PacketUtils.sendGroupedPacket(holder.players, holder.createOverlayUpdate(newOverlay)));
this.doIfRegistered(bar, holder -> PacketSendingUtils.sendGroupedPacket(holder.players, holder.createOverlayUpdate(newOverlay)));
}
@Override
public void bossBarFlagsChanged(@NotNull BossBar bar, @NotNull Set<BossBar.Flag> flagsAdded, @NotNull Set<BossBar.Flag> flagsRemoved) {
this.doIfRegistered(bar, holder -> PacketUtils.sendGroupedPacket(holder.players, holder.createFlagsUpdate()));
this.doIfRegistered(bar, holder -> PacketSendingUtils.sendGroupedPacket(holder.players, holder.createFlagsUpdate()));
}
private void doIfRegistered(@NotNull BossBar bar, @NotNull Consumer<BossBarHolder> consumer) {
BossBarHolder holder = this.manager.bars.get(bar);
if (holder != null) {
consumer.accept(holder);
}

View File

@ -4,7 +4,7 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.bossbar.BossBar;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.PacketSendingUtils;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@ -75,7 +75,7 @@ public class BossBarManager {
BossBarHolder holder = this.getOrCreateHandler(bar);
Collection<Player> addedPlayers = players.stream().filter(holder::addViewer).toList();
if (!addedPlayers.isEmpty()) {
PacketUtils.sendGroupedPacket(addedPlayers, holder.createAddPacket());
PacketSendingUtils.sendGroupedPacket(addedPlayers, holder.createAddPacket());
}
}
@ -90,7 +90,7 @@ public class BossBarManager {
if (holder != null) {
Collection<Player> removedPlayers = players.stream().filter(holder::removeViewer).toList();
if (!removedPlayers.isEmpty()) {
PacketUtils.sendGroupedPacket(removedPlayers, holder.createRemovePacket());
PacketSendingUtils.sendGroupedPacket(removedPlayers, holder.createRemovePacket());
}
}
}
@ -103,7 +103,7 @@ public class BossBarManager {
public void destroyBossBar(@NotNull BossBar bossBar) {
BossBarHolder holder = this.bars.remove(bossBar);
if (holder != null) {
PacketUtils.sendGroupedPacket(holder.players, holder.createRemovePacket());
PacketSendingUtils.sendGroupedPacket(holder.players, holder.createRemovePacket());
for (Player player : holder.players) {
this.removePlayer(player, holder);
}

View File

@ -3,7 +3,7 @@ package net.minestom.server.collision;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityPose;
import net.minestom.server.instance.block.BlockFace;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -253,7 +253,7 @@ public record BoundingBox(Vec relativeStart, Vec relativeEnd) implements Shape {
}
}
public static @Nullable BoundingBox fromPose(@NotNull Entity.Pose pose) {
public static @Nullable BoundingBox fromPose(@NotNull EntityPose pose) {
return switch (pose) {
case FALL_FLYING, SWIMMING, SPIN_ATTACK -> SMALL;
case SLEEPING, DYING -> SLEEPING;

View File

@ -3,6 +3,7 @@ package net.minestom.server.color;
import net.kyori.adventure.util.RGBLike;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.nbt.BinaryTagSerializer;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
@ -16,17 +17,11 @@ import java.util.Objects;
public final class AlphaColor extends Color {
private static final int BIT_MASK = 0xff;
public static final NetworkBuffer.Type<AlphaColor> NETWORK_TYPE = new NetworkBuffer.Type<AlphaColor>() {
@Override
public void write(@NotNull NetworkBuffer buffer, AlphaColor value) {
buffer.write(NetworkBuffer.INT, value.asARGB());
}
public static final NetworkBuffer.Type<AlphaColor> NETWORK_TYPE = NetworkBuffer.INT.transform(AlphaColor::new, AlphaColor::asARGB);
public static final BinaryTagSerializer<AlphaColor> NBT_TYPE = BinaryTagSerializer.INT.map(AlphaColor::new, AlphaColor::asARGB);
public static final AlphaColor WHITE = new AlphaColor(255, 255, 255, 255);
@Override
public AlphaColor read(@NotNull NetworkBuffer buffer) {
return new AlphaColor(buffer.read(NetworkBuffer.INT));
}
};
private final int alpha;
public AlphaColor(int alpha, int red, int green, int blue) {

View File

@ -17,19 +17,15 @@ import java.util.Objects;
public class Color implements RGBLike {
private static final int BIT_MASK = 0xff;
public static final NetworkBuffer.Type<RGBLike> NETWORK_TYPE = new NetworkBuffer.Type<RGBLike>() {
@Override
public void write(@NotNull NetworkBuffer buffer, RGBLike value) {
buffer.write(NetworkBuffer.INT, Color.fromRGBLike(value).asRGB());
}
@Override
public RGBLike read(@NotNull NetworkBuffer buffer) {
return new Color(buffer.read(NetworkBuffer.INT));
}
};
public static final NetworkBuffer.Type<RGBLike> NETWORK_TYPE = NetworkBuffer.INT.transform(
Color::new,
color -> Color.fromRGBLike(color).asRGB()
);
public static final BinaryTagSerializer<RGBLike> NBT_TYPE = BinaryTagSerializer.INT
.map(Color::new, color -> Color.fromRGBLike(color).asRGB());
public static final RGBLike WHITE = new Color(255, 255, 255);
private final int red;
private final int green;
private final int blue;

View File

@ -4,7 +4,6 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.text.Component;
import net.minestom.server.entity.Player;
import net.minestom.server.permission.PermissionHandler;
import net.minestom.server.tag.Taggable;
import org.jetbrains.annotations.NotNull;
@ -13,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
* <p>
* Main implementations are {@link Player} and {@link ConsoleSender}.
*/
public interface CommandSender extends PermissionHandler, Audience, Taggable, Identified {
public interface CommandSender extends Audience, Taggable, Identified {
/**
* Sends a raw string message.

View File

@ -1,27 +1,19 @@
package net.minestom.server.command;
import java.util.UUID;
import net.kyori.adventure.audience.MessageType;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.pointer.Pointers;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
import net.minestom.server.permission.Permission;
import net.minestom.server.tag.TagHandler;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* Represents the console when sending a command to the server.
*/
public class ConsoleSender implements CommandSender {
private static final ComponentLogger LOGGER = ComponentLogger.logger(ConsoleSender.class);
private final Set<Permission> permissions = new CopyOnWriteArraySet<>();
private final TagHandler tagHandler = TagHandler.newHandler();
private final Identity identity = Identity.nil();
@ -39,12 +31,6 @@ public class ConsoleSender implements CommandSender {
LOGGER.info(message);
}
@NotNull
@Override
public Set<Permission> getAllPermissions() {
return permissions;
}
@Override
public boolean isConsole() {
return true;

View File

@ -3,14 +3,9 @@ package net.minestom.server.command;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.identity.Identity;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.permission.Permission;
import net.minestom.server.tag.TagHandler;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* Sender used in {@link CommandManager#executeServerCommand(String)}.
* <p>
@ -20,14 +15,8 @@ import java.util.Set;
*/
public class ServerSender implements CommandSender {
private final Set<Permission> permissions = Collections.unmodifiableSet(new HashSet<>());
private final TagHandler tagHandler = TagHandler.newHandler();
@NotNull
@Override
public Set<Permission> getAllPermissions() {
return permissions;
}
@Override
public @NotNull TagHandler tagHandler() {

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.ArgumentCallback;
import net.minestom.server.command.builder.Command;
@ -7,9 +8,6 @@ import net.minestom.server.command.builder.CommandExecutor;
import net.minestom.server.command.builder.arguments.minecraft.SuggestionType;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.command.builder.suggestion.SuggestionCallback;
import net.minestom.server.registry.Registry;
import net.minestom.server.registry.StaticProtocolObject;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -29,17 +27,6 @@ import java.util.function.Supplier;
* @param <T> the type of this parsed argument
*/
public abstract class Argument<T> {
@ApiStatus.Internal
public static final Registry.Container<ArgumentImpl> CONTAINER = Registry.createStaticContainer(Registry.Resource.COMMAND_ARGUMENTS,
(namespace, properties) -> new ArgumentImpl(NamespaceID.from(namespace), properties.getInt("id")));
record ArgumentImpl(NamespaceID namespace, int id) implements StaticProtocolObject {
@Override
public String toString() {
return name();
}
}
private final String id;
protected final boolean allowSpace;
protected final boolean useRemaining;
@ -105,7 +92,7 @@ public abstract class Argument<T> {
*/
public abstract @NotNull T parse(@NotNull CommandSender sender, @NotNull String input) throws ArgumentSyntaxException;
public abstract String parser();
public abstract ArgumentParserType parser();
public byte @Nullable [] nodeProperties() {
return null;
@ -325,7 +312,7 @@ public abstract class Argument<T> {
}
@Override
public String parser() {
public ArgumentParserType parser() {
return argument.parser();
}
@ -359,7 +346,7 @@ public abstract class Argument<T> {
}
@Override
public String parser() {
public ArgumentParserType parser() {
return argument.parser();
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import org.jetbrains.annotations.NotNull;
@ -29,8 +30,8 @@ public class ArgumentBoolean extends Argument<Boolean> {
}
@Override
public String parser() {
return "brigadier:bool";
public ArgumentParserType parser() {
return ArgumentParserType.BOOL;
}
@Override
public String toString() {

View File

@ -1,6 +1,7 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.CommandDispatcher;
import net.minestom.server.command.builder.CommandResult;
@ -8,6 +9,7 @@ import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.utils.StringUtils;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ArgumentCommand extends Argument<CommandResult> {
@ -36,7 +38,7 @@ public class ArgumentCommand extends Argument<CommandResult> {
}
@Override
public String parser() {
public ArgumentParserType parser() {
return null;
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import org.jetbrains.annotations.NotNull;
@ -41,7 +42,7 @@ public class ArgumentEnum<E extends Enum> extends Argument<E> {
}
@Override
public String parser() {
public ArgumentParserType parser() {
return null;
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -39,7 +40,7 @@ public class ArgumentGroup extends Argument<CommandContext> {
}
@Override
public String parser() {
public ArgumentParserType parser() {
return null;
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import org.jetbrains.annotations.NotNull;
@ -22,7 +23,7 @@ public class ArgumentLiteral extends Argument<String> {
}
@Override
public String parser() {
public ArgumentParserType parser() {
return null;
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.utils.StringUtils;
@ -62,7 +63,7 @@ public class ArgumentLoop<T> extends Argument<List<T>> {
}
@Override
public String parser() {
public ArgumentParserType parser() {
return null;
}
}

View File

@ -1,9 +1,10 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -31,15 +32,13 @@ public class ArgumentString extends Argument<String> {
}
@Override
public String parser() {
return "brigadier:string";
public ArgumentParserType parser() {
return ArgumentParserType.STRING;
}
@Override
public byte @Nullable [] nodeProperties() {
return BinaryWriter.makeArray(packetWriter -> {
packetWriter.writeVarInt(1); // Quotable phrase
});
return NetworkBuffer.makeArray(NetworkBuffer.VAR_INT, 1); // Quotable phrase
}
/**

View File

@ -1,8 +1,9 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -26,15 +27,13 @@ public class ArgumentStringArray extends Argument<String[]> {
}
@Override
public String parser() {
return "brigadier:string";
public ArgumentParserType parser() {
return ArgumentParserType.STRING;
}
@Override
public byte @Nullable [] nodeProperties() {
return BinaryWriter.makeArray(packetWriter -> {
packetWriter.writeVarInt(2); // Greedy phrase
});
return NetworkBuffer.makeArray(NetworkBuffer.VAR_INT, 2); // Greedy phrase
}
@Override

View File

@ -1,9 +1,10 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -69,15 +70,13 @@ public class ArgumentWord extends Argument<String> {
}
@Override
public String parser() {
return "brigadier:string";
public ArgumentParserType parser() {
return ArgumentParserType.STRING;
}
@Override
public byte @Nullable [] nodeProperties() {
return BinaryWriter.makeArray(packetWriter -> {
packetWriter.writeVarInt(0); // Single word
});
return NetworkBuffer.makeArray(NetworkBuffer.VAR_INT, 0); // Single word
}
/**

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -24,8 +25,8 @@ public class ArgumentBlockState extends Argument<Block> {
}
@Override
public String parser() {
return "minecraft:block_state";
public @NotNull ArgumentParserType parser() {
return ArgumentParserType.BLOCK_STATE;
}
/**

View File

@ -2,6 +2,7 @@ package net.minestom.server.command.builder.arguments.minecraft;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -40,8 +41,8 @@ public class ArgumentColor extends Argument<Style> {
}
@Override
public String parser() {
return "minecraft:color";
public ArgumentParserType parser() {
return ArgumentParserType.COLOR;
}
@Override

View File

@ -3,6 +3,7 @@ package net.minestom.server.command.builder.arguments.minecraft;
import com.google.gson.JsonParseException;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -27,8 +28,8 @@ public class ArgumentComponent extends Argument<Component> {
}
@Override
public String parser() {
return "minecraft:component";
public ArgumentParserType parser() {
return ArgumentParserType.COMPONENT;
}
@Override

View File

@ -1,14 +1,15 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.GameMode;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.Range;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.entity.EntityFinder;
import net.minestom.server.utils.math.IntRange;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -72,13 +73,13 @@ public class ArgumentEntity extends Argument<EntityFinder> {
}
@Override
public String parser() {
return "minecraft:entity";
public ArgumentParserType parser() {
return ArgumentParserType.ENTITY;
}
@Override
public byte @Nullable [] nodeProperties() {
return BinaryWriter.makeArray(packetWriter -> {
return NetworkBuffer.makeArray(buffer -> {
byte mask = 0;
if (this.isOnlySingleEntity()) {
mask |= 0x01;
@ -86,7 +87,7 @@ public class ArgumentEntity extends Argument<EntityFinder> {
if (this.isOnlyPlayers()) {
mask |= 0x02;
}
packetWriter.writeByte(mask);
buffer.write(NetworkBuffer.BYTE, mask);
});
}
@ -252,7 +253,7 @@ public class ArgumentEntity extends Argument<EntityFinder> {
break;
case "level":
try {
final IntRange level = Argument.parse(sender, new ArgumentIntRange(value));
final Range.Int level = Argument.parse(sender, new ArgumentIntRange(value));
entityFinder.setLevel(level);
} catch (ArgumentSyntaxException e) {
throw new ArgumentSyntaxException("Invalid level number", input, INVALID_ARGUMENT_VALUE);
@ -260,7 +261,7 @@ public class ArgumentEntity extends Argument<EntityFinder> {
break;
case "distance":
try {
final IntRange distance = Argument.parse(sender, new ArgumentIntRange(value));
final Range.Int distance = Argument.parse(sender, new ArgumentIntRange(value));
entityFinder.setDistance(distance);
} catch (ArgumentSyntaxException e) {
throw new ArgumentSyntaxException("Invalid level number", input, INVALID_ARGUMENT_VALUE);

View File

@ -1,21 +1,22 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.utils.math.FloatRange;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.utils.Range;
/**
* Represents an argument which will give you an {@link FloatRange}.
* Represents an argument which will give you an {@link Range.Float}.
* <p>
* Example: ..3, 3.., 5..10, 15
*/
public class ArgumentFloatRange extends ArgumentRange<FloatRange, Float> {
public class ArgumentFloatRange extends ArgumentRange<Range.Float, Float> {
public ArgumentFloatRange(String id) {
super(id, -Float.MAX_VALUE, Float.MAX_VALUE, Float::parseFloat, FloatRange::new);
super(id, -Float.MAX_VALUE, Float.MAX_VALUE, Float::parseFloat, Range.Float::new);
}
@Override
public String parser() {
return "minecraft:float_range";
public ArgumentParserType parser() {
return ArgumentParserType.FLOAT_RANGE;
}
@Override

View File

@ -1,21 +1,22 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.utils.math.IntRange;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.utils.Range;
/**
* Represents an argument which will give you an {@link IntRange}.
* Represents an argument which will give you an {@link Range.Int}.
* <p>
* Example: ..3, 3.., 5..10, 15
*/
public class ArgumentIntRange extends ArgumentRange<IntRange, Integer> {
public class ArgumentIntRange extends ArgumentRange<Range.Int, Integer> {
public ArgumentIntRange(String id) {
super(id, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt, IntRange::new);
super(id, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt, Range.Int::new);
}
@Override
public String parser() {
return "minecraft:int_range";
public ArgumentParserType parser() {
return ArgumentParserType.INT_RANGE;
}
@Override

View File

@ -4,6 +4,7 @@ import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.nbt.TagStringIOExt;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -44,8 +45,8 @@ public class ArgumentItemStack extends Argument<ItemStack> {
}
@Override
public String parser() {
return "minecraft:item_stack";
public ArgumentParserType parser() {
return ArgumentParserType.ITEM_STACK;
}
/**

View File

@ -3,6 +3,7 @@ package net.minestom.server.command.builder.arguments.minecraft;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.nbt.TagStringIO;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -39,8 +40,8 @@ public class ArgumentNbtCompoundTag extends Argument<CompoundBinaryTag> {
}
@Override
public String parser() {
return "minecraft:nbt_compound_tag";
public ArgumentParserType parser() {
return ArgumentParserType.NBT_COMPOUND_TAG;
}
@Override

View File

@ -2,6 +2,7 @@ package net.minestom.server.command.builder.arguments.minecraft;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.TagStringIOExt;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -35,8 +36,8 @@ public class ArgumentNbtTag extends Argument<BinaryTag> {
}
@Override
public String parser() {
return "minecraft:nbt_tag";
public ArgumentParserType parser() {
return ArgumentParserType.NBT_TAG;
}
@Override

View File

@ -3,7 +3,7 @@ package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.utils.math.Range;
import net.minestom.server.utils.Range;
import org.jetbrains.annotations.NotNull;
import java.util.function.BiFunction;

View File

@ -1,10 +1,11 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -28,8 +29,8 @@ public class ArgumentResource extends Argument<String> {
}
@Override
public String parser() {
return "minecraft:resource";
public ArgumentParserType parser() {
return ArgumentParserType.RESOURCE;
}
@Override
@ -39,8 +40,6 @@ public class ArgumentResource extends Argument<String> {
@Override
public byte @Nullable [] nodeProperties() {
return BinaryWriter.makeArray(packetWriter ->
packetWriter.writeSizedString(this.identifier)
);
return NetworkBuffer.makeArray(NetworkBuffer.STRING, identifier);
}
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -24,8 +25,8 @@ public class ArgumentResourceLocation extends Argument<String> {
}
@Override
public String parser() {
return "minecraft:resource_location";
public ArgumentParserType parser() {
return ArgumentParserType.RESOURCE_LOCATION;
}
@Override

View File

@ -1,10 +1,11 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -28,8 +29,8 @@ public class ArgumentResourceOrTag extends Argument<String> {
}
@Override
public String parser() {
return "minecraft:resource_or_tag";
public ArgumentParserType parser() {
return ArgumentParserType.RESOURCE_OR_TAG;
}
@Override
@ -39,8 +40,6 @@ public class ArgumentResourceOrTag extends Argument<String> {
@Override
public byte @Nullable [] nodeProperties() {
return BinaryWriter.makeArray(packetWriter ->
packetWriter.writeSizedString(this.identifier)
);
return NetworkBuffer.makeArray(NetworkBuffer.STRING, identifier);
}
}

View File

@ -2,10 +2,11 @@ package net.minestom.server.command.builder.arguments.minecraft;
import it.unimi.dsi.fastutil.chars.CharArrayList;
import it.unimi.dsi.fastutil.chars.CharList;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -70,14 +71,12 @@ public class ArgumentTime extends Argument<Duration> {
@Override
public byte @Nullable [] nodeProperties() {
return BinaryWriter.makeArray(packetWriter -> {
packetWriter.writeInt(min);
});
return NetworkBuffer.makeArray(NetworkBuffer.INT, min);
}
@Override
public String parser() {
return "minecraft:time";
public ArgumentParserType parser() {
return ArgumentParserType.TIME;
}
@Override

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
@ -26,8 +27,8 @@ public class ArgumentUUID extends Argument<UUID> {
}
@Override
public String parser() {
return "minecraft:uuid";
public ArgumentParserType parser() {
return ArgumentParserType.UUID;
}
@Override

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments.minecraft.registry;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.builder.arguments.minecraft.SuggestionType;
import net.minestom.server.entity.EntityType;
import org.jetbrains.annotations.NotNull;
@ -15,8 +16,8 @@ public class ArgumentEntityType extends ArgumentRegistry<EntityType> {
}
@Override
public String parser() {
return "minecraft:resource_location";
public ArgumentParserType parser() {
return ArgumentParserType.RESOURCE_LOCATION;
}
@Override

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments.minecraft.registry;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.particle.Particle;
import org.jetbrains.annotations.NotNull;
@ -13,8 +14,8 @@ public class ArgumentParticle extends ArgumentRegistry<Particle> {
}
@Override
public String parser() {
return "minecraft:particle";
public ArgumentParserType parser() {
return ArgumentParserType.PARTICLE;
}
@Override

View File

@ -1,11 +1,13 @@
package net.minestom.server.command.builder.arguments.number;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.network.NetworkBuffer;
public class ArgumentDouble extends ArgumentNumber<Double> {
public ArgumentDouble(String id) {
super(id, "brigadier:double", Double::parseDouble, ((s, radix) -> (double) Long.parseLong(s, radix)), BinaryWriter::writeDouble, Double::compare);
super(id, ArgumentParserType.DOUBLE, Double::parseDouble, ((s, radix) -> (double) Long.parseLong(s, radix)),
NetworkBuffer.DOUBLE, Double::compare);
}
@Override

View File

@ -1,11 +1,13 @@
package net.minestom.server.command.builder.arguments.number;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.network.NetworkBuffer;
public class ArgumentFloat extends ArgumentNumber<Float> {
public ArgumentFloat(String id) {
super(id, "brigadier:float", Float::parseFloat, (s, radix) -> (float) Integer.parseInt(s, radix), BinaryWriter::writeFloat, Float::compare);
super(id, ArgumentParserType.FLOAT, Float::parseFloat, (s, radix) -> (float) Integer.parseInt(s, radix),
NetworkBuffer.FLOAT, Float::compare);
}
@Override

View File

@ -1,11 +1,13 @@
package net.minestom.server.command.builder.arguments.number;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.network.NetworkBuffer;
public class ArgumentInteger extends ArgumentNumber<Integer> {
public ArgumentInteger(String id) {
super(id, "brigadier:integer", Integer::parseInt, Integer::parseInt, BinaryWriter::writeInt, Integer::compare);
super(id, ArgumentParserType.INTEGER, Integer::parseInt, Integer::parseInt,
NetworkBuffer.INT, Integer::compare);
}
@Override

View File

@ -1,11 +1,13 @@
package net.minestom.server.command.builder.arguments.number;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.network.NetworkBuffer;
public class ArgumentLong extends ArgumentNumber<Long> {
public ArgumentLong(String id) {
super(id, "brigadier:long", Long::parseLong, Long::parseLong, BinaryWriter::writeLong, Long::compare);
super(id, ArgumentParserType.LONG, Long::parseLong, Long::parseLong,
NetworkBuffer.LONG, Long::compare);
}
@Override

View File

@ -1,15 +1,15 @@
package net.minestom.server.command.builder.arguments.number;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.network.NetworkBuffer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.regex.Pattern;
@ -23,20 +23,20 @@ public class ArgumentNumber<T extends Number> extends Argument<T> {
protected boolean hasMin, hasMax;
protected T min, max;
protected final String parserName;
protected final ArgumentParserType parserName;
protected final BiFunction<String, Integer, T> radixParser;
protected final Function<String, T> parser;
protected final BiConsumer<BinaryWriter, T> propertiesWriter;
protected final NetworkBuffer.Type<T> networkType;
protected final Comparator<T> comparator;
ArgumentNumber(@NotNull String id, String parserName, Function<String, T> parser,
BiFunction<String, Integer, T> radixParser, BiConsumer<BinaryWriter, T> propertiesWriter,
ArgumentNumber(@NotNull String id, ArgumentParserType parserName, Function<String, T> parser,
BiFunction<String, Integer, T> radixParser, NetworkBuffer.Type<T> networkType,
Comparator<T> comparator) {
super(id);
this.parserName = parserName;
this.radixParser = radixParser;
this.parser = parser;
this.propertiesWriter = propertiesWriter;
this.networkType = networkType;
this.comparator = comparator;
}
@ -66,18 +66,18 @@ public class ArgumentNumber<T extends Number> extends Argument<T> {
}
@Override
public String parser() {
public ArgumentParserType parser() {
return parserName;
}
@Override
public byte @Nullable [] nodeProperties() {
return BinaryWriter.makeArray(packetWriter -> {
packetWriter.writeByte(getNumberProperties());
return NetworkBuffer.makeArray(buffer -> {
buffer.write(NetworkBuffer.BYTE, getNumberProperties());
if (this.hasMin())
propertiesWriter.accept(packetWriter, getMin());
networkType.write(buffer, getMin());
if (this.hasMax())
propertiesWriter.accept(packetWriter, getMax());
networkType.write(buffer, getMax());
});
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments.relative;
import net.minestom.server.command.ArgumentParserType;
import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
@ -16,8 +17,8 @@ public class ArgumentRelativeBlockPosition extends ArgumentRelativeVec {
}
@Override
public String parser() {
return "minecraft:block_pos";
public ArgumentParserType parser() {
return ArgumentParserType.BLOCK_POS;
}
@Override

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments.relative;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
@ -17,8 +18,8 @@ public class ArgumentRelativeVec2 extends ArgumentRelativeVec {
}
@Override
public String parser() {
return "minecraft:vec2";
public ArgumentParserType parser() {
return ArgumentParserType.VEC2;
}
@Override

View File

@ -1,5 +1,6 @@
package net.minestom.server.command.builder.arguments.relative;
import net.minestom.server.command.ArgumentParserType;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull;
@ -17,8 +18,8 @@ public class ArgumentRelativeVec3 extends ArgumentRelativeVec {
}
@Override
public String parser() {
return "minecraft:vec3";
public ArgumentParserType parser() {
return ArgumentParserType.VEC3;
}
@Override

View File

@ -0,0 +1,84 @@
package net.minestom.server.coordinate;
import org.jetbrains.annotations.NotNull;
/**
* Helper class to iterate over chunks within a range.
*/
public final class ChunkRange {
/**
* Get the amount of chunks in a square range.
*
* @param range the range
* @return the amount of chunks in the square range
*/
public static int chunksCount(int range) {
if (range < 0) throw new IllegalArgumentException("Range cannot be negative");
final int square = range * 2 + 1;
return square * square;
}
public static void chunksInRangeDiffering(int newChunkX, int newChunkZ,
int oldChunkX, int oldChunkZ,
int range, @NotNull ChunkConsumer callback) {
for (int x = newChunkX - range; x <= newChunkX + range; x++) {
for (int z = newChunkZ - range; z <= newChunkZ + range; z++) {
if (Math.abs(x - oldChunkX) > range || Math.abs(z - oldChunkZ) > range) {
callback.accept(x, z);
}
}
}
}
public static void chunksInRangeDiffering(int newChunkX, int newChunkZ,
int oldChunkX, int oldChunkZ,
int range,
@NotNull ChunkConsumer newCallback, @NotNull ChunkConsumer oldCallback) {
// Find the new chunks
chunksInRangeDiffering(newChunkX, newChunkZ, oldChunkX, oldChunkZ, range, newCallback);
// Find the old chunks
chunksInRangeDiffering(oldChunkX, oldChunkZ, newChunkX, newChunkZ, range, oldCallback);
}
/**
* New implementation comes from <a href="https://github.com/KryptonMC/Krypton/blob/a9eff5463328f34072cdaf37aae3e77b14fcac93/server/src/main/kotlin/org/kryptonmc/krypton/util/math/Maths.kt#L62">Krypton</a>
* which comes from kotlin port by <a href="https://github.com/Esophose">Esophose</a>, which comes from <a href="https://stackoverflow.com/questions/398299/looping-in-a-spiral">a stackoverflow answer</a>.
*/
public static void chunksInRange(int chunkX, int chunkZ, int range, ChunkConsumer consumer) {
// Send in spiral around the center chunk
// Note: its not really required to start at the center anymore since the chunk queue is sorted by distance,
// however we still should send a circle so this method is still fine, and good for any other case a
// spiral might be needed.
consumer.accept(chunkX, chunkZ);
for (int id = 1; id < (range * 2 + 1) * (range * 2 + 1); id++) {
final int index = id - 1;
// compute radius (inverse arithmetic sum of 8 + 16 + 24 + ...)
final int radius = (int) Math.floor((Math.sqrt(index + 1.0) - 1) / 2) + 1;
// compute total point on radius -1 (arithmetic sum of 8 + 16 + 24 + ...)
final int p = 8 * radius * (radius - 1) / 2;
// points by face
final int en = radius * 2;
// compute de position and shift it so the first is (-r, -r) but (-r + 1, -r)
// so the square can connect
final int a = (1 + index - p) % (radius * 8);
switch (a / (radius * 2)) {
// find the face (0 = top, 1 = right, 2 = bottom, 3 = left)
case 0 -> consumer.accept(a - radius + chunkX, -radius + chunkZ);
case 1 -> consumer.accept(radius + chunkX, a % en - radius + chunkZ);
case 2 -> consumer.accept(radius - a % en + chunkX, radius + chunkZ);
case 3 -> consumer.accept(-radius + chunkX, radius - a % en + chunkZ);
default -> throw new IllegalStateException("unreachable");
}
}
}
public static void chunksInRange(@NotNull Point point, int range, ChunkConsumer consumer) {
chunksInRange(point.chunkX(), point.chunkZ(), range, consumer);
}
@FunctionalInterface
public interface ChunkConsumer {
void accept(int chunkX, int chunkZ);
}
}

View File

@ -0,0 +1,97 @@
package net.minestom.server.coordinate;
import org.jetbrains.annotations.NotNull;
public final class CoordConversion {
// COORDINATE CONVERSIONS
public static int globalToBlock(double xyz) {
return (int) Math.floor(xyz);
}
public static int globalToChunk(double xz) {
final int block = globalToBlock(xz);
return globalToChunk(block);
}
public static int globalToChunk(int xz) {
// Assume chunk/section size being 16 (4 bits)
return xz >> 4;
}
public static int globalToSectionRelative(int xyz) {
return xyz & 0xF;
}
public static int chunkToRegion(int chunkCoordinate) {
return chunkCoordinate >> 5;
}
public static int chunkToRegionLocal(int chunkCoordinate) {
return chunkCoordinate & 0x1F;
}
public static int floorSection(int coordinate) {
return coordinate - (coordinate & 0xF);
}
public static int ceilSection(int coordinate) {
return ((coordinate - 1) | 15) + 1;
}
// CHUNK INDEX
public static long chunkIndex(int chunkX, int chunkZ) {
return (((long) chunkX) << 32) | (chunkZ & 0xffffffffL);
}
public static long chunkIndex(@NotNull Point point) {
return chunkIndex(point.chunkX(), point.chunkZ());
}
public static int chunkIndexGetX(long index) {
return (int) (index >> 32);
}
public static int chunkIndexGetZ(long index) {
return (int) index;
}
// BLOCK INDEX FROM CHUNK
public static int chunkBlockIndex(int x, int y, int z) {
x = globalToSectionRelative(x);
z = globalToSectionRelative(z);
int index = x & 0xF; // 4 bits
if (y > 0) {
index |= (y << 4) & 0x07FFFFF0; // 23 bits (24th bit is always 0 because y is positive)
} else {
index |= ((-y) << 4) & 0x7FFFFF0; // Make positive and use 23 bits
index |= 1 << 27; // Set negative sign at 24th bit
}
index |= (z << 28) & 0xF0000000; // 4 bits
return index;
}
public static int chunkBlockIndexGetX(int index) {
return index & 0xF; // 0-4 bits
}
public static int chunkBlockIndexGetY(int index) {
int y = (index & 0x07FFFFF0) >>> 4;
if (((index >>> 27) & 1) == 1) y = -y; // Sign bit set, invert sign
return y; // 4-28 bits
}
public static int chunkBlockIndexGetZ(int index) {
return (index >> 28) & 0xF; // 28-32 bits
}
public static @NotNull Point chunkBlockIndexGetGlobal(int index, int chunkX, int chunkZ) {
final int x = chunkBlockIndexGetX(index) + 16 * chunkX;
final int y = chunkBlockIndexGetY(index);
final int z = chunkBlockIndexGetZ(index) + 16 * chunkZ;
return new Vec(x, y, z);
}
}

View File

@ -2,12 +2,14 @@ package net.minestom.server.coordinate;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.chunk.ChunkUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.function.DoubleUnaryOperator;
import static net.minestom.server.coordinate.CoordConversion.globalToBlock;
import static net.minestom.server.coordinate.CoordConversion.globalToChunk;
/**
* Represents a 3D point.
*/
@ -44,7 +46,7 @@ public sealed interface Point permits Vec, Pos, BlockVec {
*/
@Contract(pure = true)
default int blockX() {
return (int) Math.floor(x());
return globalToBlock(x());
}
/**
@ -54,7 +56,7 @@ public sealed interface Point permits Vec, Pos, BlockVec {
*/
@Contract(pure = true)
default int blockY() {
return (int) Math.floor(y());
return globalToBlock(y());
}
/**
@ -64,22 +66,22 @@ public sealed interface Point permits Vec, Pos, BlockVec {
*/
@Contract(pure = true)
default int blockZ() {
return (int) Math.floor(z());
return globalToBlock(z());
}
@Contract(pure = true)
default int chunkX() {
return ChunkUtils.getChunkCoordinate(x());
return globalToChunk(x());
}
@Contract(pure = true)
default int section() {
return ChunkUtils.getChunkCoordinate(y());
return globalToChunk(y());
}
@Contract(pure = true)
default int chunkZ() {
return ChunkUtils.getChunkCoordinate(z());
return globalToChunk(z());
}
/**

View File

@ -1,37 +1,30 @@
package net.minestom.server.crypto;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.NetworkBufferTemplate;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import static net.minestom.server.network.NetworkBuffer.STRING;
public record ArgumentSignatures(@NotNull List<@NotNull Entry> entries) implements NetworkBuffer.Writer {
public record ArgumentSignatures(@NotNull List<@NotNull Entry> entries) {
public static final int MAX_ENTRIES = 8;
public ArgumentSignatures {
entries = List.copyOf(entries);
}
public ArgumentSignatures(@NotNull NetworkBuffer reader) {
this(reader.readCollection(Entry::new, MAX_ENTRIES));
}
public static final NetworkBuffer.Type<ArgumentSignatures> SERIALIZER = NetworkBufferTemplate.template(
Entry.SERIALIZER.list(MAX_ENTRIES), ArgumentSignatures::entries,
ArgumentSignatures::new
);
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.writeCollection(entries);
}
public record Entry(@NotNull String name, @NotNull MessageSignature signature) implements NetworkBuffer.Writer {
public Entry(@NotNull NetworkBuffer reader) {
this(reader.read(STRING), new MessageSignature(reader));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(STRING, name);
writer.write(signature);
}
public record Entry(@NotNull String name, @NotNull MessageSignature signature) {
public static final NetworkBuffer.Type<Entry> SERIALIZER = NetworkBufferTemplate.template(
STRING, Entry::name,
MessageSignature.SERIALIZER, Entry::signature,
Entry::new
);
}
}

View File

@ -1,18 +1,17 @@
package net.minestom.server.crypto;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.NetworkBufferTemplate;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public record ChatSession(@NotNull UUID sessionId, @NotNull PlayerPublicKey publicKey) implements NetworkBuffer.Writer {
public ChatSession(@NotNull NetworkBuffer reader) {
this(reader.read(NetworkBuffer.UUID), new PlayerPublicKey(reader));
}
import static net.minestom.server.network.NetworkBuffer.UUID;
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.UUID, sessionId);
writer.write(publicKey);
}
public record ChatSession(@NotNull UUID sessionId, @NotNull PlayerPublicKey publicKey) {
public static final NetworkBuffer.Type<ChatSession> SERIALIZER = NetworkBufferTemplate.template(
UUID, ChatSession::sessionId,
PlayerPublicKey.SERIALIZER, ChatSession::publicKey,
ChatSession::new
);
}

View File

@ -5,20 +5,25 @@ import org.jetbrains.annotations.NotNull;
import java.util.BitSet;
import static net.minestom.server.network.NetworkBuffer.LONG_ARRAY;
import static net.minestom.server.network.NetworkBuffer.BITSET;
public record FilterMask(@NotNull Type type, @NotNull BitSet mask) implements NetworkBuffer.Writer {
public FilterMask(@NotNull NetworkBuffer reader) {
this(reader.readEnum(Type.class), BitSet.valueOf(reader.read(LONG_ARRAY)));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.writeEnum(Type.class, type);
if (type == Type.PARTIALLY_FILTERED) {
writer.write(LONG_ARRAY, mask.toLongArray());
public record FilterMask(@NotNull Type type, @NotNull BitSet mask) {
public static final NetworkBuffer.Type<FilterMask> SERIALIZER = new NetworkBuffer.Type<>() {
@Override
public void write(@NotNull NetworkBuffer buffer, FilterMask value) {
buffer.write(NetworkBuffer.Enum(Type.class), value.type);
if (value.type == Type.PARTIALLY_FILTERED) {
buffer.write(BITSET, value.mask);
}
}
}
@Override
public FilterMask read(@NotNull NetworkBuffer buffer) {
Type type = buffer.read(NetworkBuffer.Enum(Type.class));
BitSet mask = type == Type.PARTIALLY_FILTERED ? buffer.read(BITSET) : new BitSet();
return new FilterMask(type, mask);
}
};
public enum Type {
PASS_THROUGH,

View File

@ -1,50 +1,41 @@
package net.minestom.server.crypto;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.NetworkBufferTemplate;
import org.jetbrains.annotations.NotNull;
import java.util.BitSet;
import java.util.List;
import static net.minestom.server.network.NetworkBuffer.FixedBitSet;
import static net.minestom.server.network.NetworkBuffer.VAR_INT;
public record LastSeenMessages(@NotNull List<@NotNull MessageSignature> entries) implements NetworkBuffer.Writer {
public record LastSeenMessages(@NotNull List<@NotNull MessageSignature> entries) {
public static final int MAX_ENTRIES = 20;
public LastSeenMessages {
entries = List.copyOf(entries);
}
public LastSeenMessages(@NotNull NetworkBuffer reader) {
this(reader.readCollection(MessageSignature::new, MAX_ENTRIES));
}
public static final NetworkBuffer.Type<LastSeenMessages> SERIALIZER = NetworkBufferTemplate.template(
MessageSignature.SERIALIZER.list(MAX_ENTRIES), LastSeenMessages::entries,
LastSeenMessages::new
);
@Override
public void write(@NotNull NetworkBuffer writer) {
}
public record Packed(@NotNull List<MessageSignature.@NotNull Packed> entries) implements NetworkBuffer.Writer {
public record Packed(@NotNull List<MessageSignature.@NotNull Packed> entries) {
public static final Packed EMPTY = new Packed(List.of());
public Packed(@NotNull NetworkBuffer reader) {
this(reader.readCollection(MessageSignature.Packed::new, MAX_ENTRIES));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.writeCollection(entries);
}
public static final NetworkBuffer.Type<Packed> SERIALIZER = NetworkBufferTemplate.template(
MessageSignature.Packed.SERIALIZER.list(MAX_ENTRIES), Packed::entries,
Packed::new
);
}
public record Update(int offset, @NotNull BitSet acknowledged) implements NetworkBuffer.Writer {
public Update(@NotNull NetworkBuffer reader) {
this(reader.read(VAR_INT), reader.readFixedBitSet(20));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(VAR_INT, offset);
writer.writeFixedBitSet(acknowledged, 20);
}
public record Update(int offset, @NotNull BitSet acknowledged) {
public static final NetworkBuffer.Type<Update> SERIALIZER = NetworkBufferTemplate.template(
VAR_INT, Update::offset,
FixedBitSet(20), Update::acknowledged,
Update::new
);
}
}

View File

@ -1,14 +1,13 @@
package net.minestom.server.crypto;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.NetworkBufferTemplate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnknownNullability;
import static net.minestom.server.network.NetworkBuffer.RAW_BYTES;
import static net.minestom.server.network.NetworkBuffer.VAR_INT;
public record MessageSignature(byte @NotNull [] signature) implements NetworkBuffer.Writer {
public record MessageSignature(byte @NotNull [] signature) {
static final int SIGNATURE_BYTE_LENGTH = 256;
public MessageSignature {
@ -17,33 +16,28 @@ public record MessageSignature(byte @NotNull [] signature) implements NetworkBuf
}
}
public MessageSignature(@NotNull NetworkBuffer reader) {
this(reader.readBytes(SIGNATURE_BYTE_LENGTH));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(RAW_BYTES, signature);
}
public record Packed(int id, @UnknownNullability MessageSignature fullSignature) implements NetworkBuffer.Writer {
public Packed(@NotNull NetworkBuffer reader) {
this(read(reader));
}
public static final NetworkBuffer.Type<MessageSignature> SERIALIZER = NetworkBufferTemplate.template(
NetworkBuffer.RAW_BYTES, MessageSignature::signature,
MessageSignature::new
);
public record Packed(int id, @UnknownNullability MessageSignature fullSignature) {
private Packed(@NotNull Packed packed) {
this(packed.id, packed.fullSignature);
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(VAR_INT, id + 1);
if (id == 0) writer.write(fullSignature);
}
public static final NetworkBuffer.Type<Packed> SERIALIZER = new NetworkBuffer.Type<>() {
@Override
public void write(@NotNull NetworkBuffer buffer, Packed value) {
buffer.write(VAR_INT, value.id + 1);
if (value.id == 0) buffer.write(MessageSignature.SERIALIZER, value.fullSignature);
}
private static Packed read(NetworkBuffer reader) {
final int id = reader.read(VAR_INT) - 1;
return new Packed(id, id == -1 ? new MessageSignature(reader) : null);
}
@Override
public Packed read(@NotNull NetworkBuffer buffer) {
final int id = buffer.read(VAR_INT) - 1;
return new Packed(id, id == -1 ? buffer.read(MessageSignature.SERIALIZER) : null);
}
};
}
}

View File

@ -1,39 +1,21 @@
package net.minestom.server.crypto;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.utils.crypto.KeyUtils;
import org.jetbrains.annotations.NotNull;
import net.minestom.server.network.NetworkBufferTemplate;
import java.security.PublicKey;
import java.time.Instant;
import java.util.Arrays;
import static net.minestom.server.network.NetworkBuffer.BYTE_ARRAY;
import static net.minestom.server.network.NetworkBuffer.LONG;
import static net.minestom.server.network.NetworkBuffer.*;
/**
* Player's public key used to sign chat messages
*/
public record PlayerPublicKey(Instant expiresAt, PublicKey publicKey,
byte[] signature) implements NetworkBuffer.Writer {
public PlayerPublicKey(@NotNull NetworkBuffer reader) {
this(Instant.ofEpochMilli(reader.read(LONG)),
KeyUtils.publicRSAKeyFrom(reader.read(BYTE_ARRAY)), reader.read(BYTE_ARRAY));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(LONG, expiresAt().toEpochMilli());
writer.write(BYTE_ARRAY, publicKey.getEncoded());
writer.write(BYTE_ARRAY, signature());
}
@Override
public boolean equals(Object obj) {
if (obj instanceof PlayerPublicKey ppk) {
return expiresAt.equals(ppk.expiresAt) && publicKey.equals(ppk.publicKey) && Arrays.equals(signature, ppk.signature);
} else {
return false;
}
}
public record PlayerPublicKey(Instant expiresAt, PublicKey publicKey, byte[] signature) {
public static final NetworkBuffer.Type<PlayerPublicKey> SERIALIZER = NetworkBufferTemplate.template(
INSTANT_MS, PlayerPublicKey::expiresAt,
PUBLIC_KEY, PlayerPublicKey::publicKey,
BYTE_ARRAY, PlayerPublicKey::signature,
PlayerPublicKey::new
);
}

View File

@ -1,19 +1,12 @@
package net.minestom.server.crypto;
import net.minestom.server.network.NetworkBuffer;
import org.jetbrains.annotations.NotNull;
import net.minestom.server.network.NetworkBufferTemplate;
import static net.minestom.server.network.NetworkBuffer.BYTE_ARRAY;
import static net.minestom.server.network.NetworkBuffer.LONG;
public record SaltSignaturePair(long salt, byte[] signature) implements NetworkBuffer.Writer {
public SaltSignaturePair(@NotNull NetworkBuffer reader) {
this(reader.read(LONG), reader.read(BYTE_ARRAY));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(LONG, salt);
writer.write(BYTE_ARRAY, signature);
}
public record SaltSignaturePair(long salt, byte[] signature) {
public static final NetworkBuffer.Type<SaltSignaturePair> SERIALIZER = NetworkBufferTemplate.template(
NetworkBuffer.LONG, SaltSignaturePair::salt,
NetworkBuffer.BYTE_ARRAY, SaltSignaturePair::signature,
SaltSignaturePair::new
);
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.crypto;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.NetworkBufferTemplate;
import org.jetbrains.annotations.NotNull;
import java.time.Instant;
@ -8,24 +9,19 @@ import java.time.Instant;
public final class SignedMessageBody {
public record Packed(@NotNull String content, @NotNull Instant timeStamp, long salt,
LastSeenMessages.@NotNull Packed lastSeen) implements NetworkBuffer.Writer {
LastSeenMessages.@NotNull Packed lastSeen) {
public Packed {
if (content.length() > MessageSignature.SIGNATURE_BYTE_LENGTH) {
throw new IllegalArgumentException("Message content too long");
}
}
public Packed(@NotNull NetworkBuffer reader) {
this(reader.read(NetworkBuffer.STRING), Instant.ofEpochMilli(reader.read(NetworkBuffer.LONG)),
reader.read(NetworkBuffer.LONG), new LastSeenMessages.Packed(reader));
}
@Override
public void write(@NotNull NetworkBuffer writer) {
writer.write(NetworkBuffer.STRING, content);
writer.write(NetworkBuffer.LONG, timeStamp.toEpochMilli());
writer.write(NetworkBuffer.LONG, salt);
writer.write(lastSeen);
}
public static final NetworkBuffer.Type<Packed> SERIALIZER = NetworkBufferTemplate.template(
NetworkBuffer.STRING, Packed::content,
NetworkBuffer.INSTANT_MS, Packed::timeStamp,
NetworkBuffer.LONG, Packed::salt,
LastSeenMessages.Packed.SERIALIZER, Packed::lastSeen,
Packed::new
);
}
}

Some files were not shown because too many files have changed in this diff Show More