diff --git a/build.gradle.kts b/build.gradle.kts index b1916f02d..f8259daf4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,6 +24,7 @@ allprojects { repositories { mavenCentral() + mavenLocal() maven(url = "https://jitpack.io") } diff --git a/code-generators/src/main/java/net/minestom/codegen/Generators.java b/code-generators/src/main/java/net/minestom/codegen/Generators.java index 6cb6ded57..26688c331 100644 --- a/code-generators/src/main/java/net/minestom/codegen/Generators.java +++ b/code-generators/src/main/java/net/minestom/codegen/Generators.java @@ -18,11 +18,9 @@ public class Generators { } File outputFolder = new File(args[0]); - // Generate DyeColors new DyeColorGenerator(resource("dye_colors.json"), outputFolder).generate(); - var generator = new CodeGenerator(outputFolder); generator.generate(resource("blocks.json"), "net.minestom.server.instance.block", "Block", "BlockImpl", "Blocks"); generator.generate(resource("items.json"), "net.minestom.server.item", "Material", "MaterialImpl", "Materials"); @@ -37,16 +35,11 @@ public class Generators { generator.generate(resource("damage_types.json"), "net.minestom.server.entity.damage", "DamageType", "DamageTypeImpl", "DamageTypes"); generator.generate(resource("trim_materials.json"), "net.minestom.server.item.armor", "TrimMaterial", "TrimMaterialImpl", "TrimMaterials"); generator.generate(resource("trim_patterns.json"), "net.minestom.server.item.armor", "TrimPattern", "TrimPatternImpl", "TrimPatterns"); - + generator.generate(resource("attributes.json"), "net.minestom.server.entity.attribute", "Attribute", "AttributeImpl", "Attributes"); // Generate fluids new FluidGenerator(resource("fluids.json"), outputFolder).generate(); - // TODO: Generate attributes -// new AttributeGenerator( -// new File(inputFolder, targetVersion + "_attributes.json"), -// outputFolder -// ).generate(); // TODO: Generate villager professions // new VillagerProfessionGenerator( // new File(inputFolder, targetVersion + "_villager_professions.json"), diff --git a/code-generators/src/main/java/net/minestom/codegen/attribute/AttributeGenerator.java b/code-generators/src/main/java/net/minestom/codegen/attribute/AttributeGenerator.java deleted file mode 100644 index 11ee9eef8..000000000 --- a/code-generators/src/main/java/net/minestom/codegen/attribute/AttributeGenerator.java +++ /dev/null @@ -1,249 +0,0 @@ -package net.minestom.codegen.attribute; - -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.ArrayList; -import java.util.List; - -public final class AttributeGenerator extends MinestomCodeGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(AttributeGenerator.class); - private final InputStream attributesFile; - private final File outputFolder; - - public AttributeGenerator(@Nullable InputStream attributesFile, @NotNull File outputFolder) { - this.attributesFile = attributesFile; - this.outputFolder = outputFolder; - } - - @Override - public void generate() { - if (attributesFile == null) { - LOGGER.error("Failed to find attributes.json."); - LOGGER.error("Stopped code generation for attributes."); - return; - } - if (!outputFolder.exists() && !outputFolder.mkdirs()) { - LOGGER.error("Output folder for code generation does not exist and could not be created."); - return; - } - // Important classes we use alot - ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID"); - ClassName registryClassName = ClassName.get("net.minestom.server.registry", "Registry"); - - JsonArray attributes = GSON.fromJson(new InputStreamReader(attributesFile), JsonArray.class); - List filesToWrite = new ArrayList<>(); - - ClassName attributeClassName = ClassName.get("net.minestom.server.attribute", "Attribute"); - - // Attribute - TypeSpec.Builder attributeClass = TypeSpec.classBuilder(attributeClassName) - .addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed")) - .addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName()); - attributeClass.addField( - FieldSpec.builder(namespaceIDClassName, "id") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build() - ); - attributeClass.addField( - FieldSpec.builder(TypeName.DOUBLE, "defaultValue") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL).build() - ); - attributeClass.addField( - FieldSpec.builder(TypeName.BOOLEAN, "clientSyncable") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL).build() - ); - attributeClass.addMethod( - MethodSpec.constructorBuilder() - .addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build()) - .addParameter(ParameterSpec.builder(TypeName.BOOLEAN, "clientSyncable").build()) - .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "defaultValue").build()) - .addStatement("this.id = id") - .addStatement("this.clientSyncable = clientSyncable") - .addStatement("this.defaultValue = defaultValue") - .addModifiers(Modifier.PROTECTED) - .build() - ); - // Override key method (adventure) - attributeClass.addMethod( - MethodSpec.methodBuilder("key") - .returns(ClassName.get("net.kyori.adventure.key", "Key")) - .addAnnotation(Override.class) - .addAnnotation(NotNull.class) - .addStatement("return this.id") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getId method - attributeClass.addMethod( - MethodSpec.methodBuilder("getId") - .returns(namespaceIDClassName) - .addAnnotation(NotNull.class) - .addStatement("return this.id") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getDefaultValue - attributeClass.addMethod( - MethodSpec.methodBuilder("getDefaultValue") - .returns(TypeName.DOUBLE) - .addStatement("return this.defaultValue") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // isClientSyncable - attributeClass.addMethod( - MethodSpec.methodBuilder("isClientSyncable") - .returns(TypeName.BOOLEAN) - .addStatement("return this.clientSyncable") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // isShared - attributeClass.addMethod( - MethodSpec.methodBuilder("isShared") - .addAnnotation(Deprecated.class) - .returns(TypeName.BOOLEAN) - .addStatement("return this.clientSyncable") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // values method - attributeClass.addMethod( - MethodSpec.methodBuilder("values") - .addAnnotation(NotNull.class) - .returns(ParameterizedTypeName.get(ClassName.get(List.class), attributeClassName)) - .addStatement("return $T.ATTRIBUTE_REGISTRY.values()", registryClassName) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .build() - ); - // toString method - attributeClass.addMethod( - MethodSpec.methodBuilder("toString") - .addAnnotation(NotNull.class) - .addAnnotation(Override.class) - .returns(String.class) - // this resolves to [Namespace] - .addStatement("return \"[\" + this.id + \"]\"") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // Creating ClampedAttribute - ClassName clampedAttributeClassName = ClassName.get("net.minestom.server.attribute", "ClampedAttribute"); - - TypeSpec.Builder clampedAttributeClass = TypeSpec.classBuilder(clampedAttributeClassName) - .superclass(attributeClassName) - .addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName()); - clampedAttributeClass.addField( - FieldSpec.builder(TypeName.DOUBLE, "minValue") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL).build() - ); - clampedAttributeClass.addField( - FieldSpec.builder(TypeName.DOUBLE, "maxValue") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL).build() - ); - clampedAttributeClass.addMethod( - MethodSpec.constructorBuilder() - .addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build()) - .addParameter(ParameterSpec.builder(TypeName.BOOLEAN, "clientSyncable").build()) - .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "defaultValue").build()) - .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "minValue").build()) - .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "maxValue").build()) - .addStatement("super(id, clientSyncable, defaultValue)") - .addStatement("this.minValue = minValue") - .addStatement("this.maxValue = maxValue") - .addModifiers(Modifier.PROTECTED) - .build() - ); - // getMinValue - clampedAttributeClass.addMethod( - MethodSpec.methodBuilder("getMinValue") - .returns(TypeName.DOUBLE) - .addStatement("return this.minValue") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getMaxValue - clampedAttributeClass.addMethod( - MethodSpec.methodBuilder("getMaxValue") - .returns(TypeName.DOUBLE) - .addStatement("return this.maxValue") - .addModifiers(Modifier.PUBLIC) - .build() - ); - - CodeBlock.Builder staticBlock = CodeBlock.builder(); - // Use data - for (JsonElement a : attributes) { - JsonObject attribute = a.getAsJsonObject(); - String attributeName = attribute.get("name").getAsString(); - - JsonObject range = attribute.getAsJsonObject("range"); - if (range == null) { - // Normal attribute - attributeClass.addField( - FieldSpec.builder( - attributeClassName, - attributeName - ).initializer( - "new $T($T.from($S), $L, $L)", - attributeClassName, - namespaceIDClassName, - attribute.get("id").getAsString(), - attribute.get("clientSync").getAsBoolean(), - attribute.get("defaultValue").getAsDouble() - ).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build() - ); - } else { - // ClampedAttribute - attributeClass.addField( - FieldSpec.builder( - attributeClassName, - attributeName - ).initializer( - "new $T($T.from($S), $L, $L, $L, $L)", - clampedAttributeClassName, - namespaceIDClassName, - attribute.get("id").getAsString(), - attribute.get("clientSync").getAsBoolean(), - attribute.get("defaultValue").getAsDouble(), - range.get("minValue").getAsDouble(), - range.get("maxValue").getAsDouble() - ).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build() - ); - } - // Add to static init. - staticBlock.addStatement("$T.ATTRIBUTE_REGISTRY.register($N)", registryClassName, attributeName); - } - attributeClass.addStaticBlock(staticBlock.build()); - - filesToWrite.add( - JavaFile.builder("net.minestom.server.attribute", attributeClass.build()) - .indent(" ") - .skipJavaLangImports(true) - .build() - ); - filesToWrite.add( - JavaFile.builder("net.minestom.server.attribute", clampedAttributeClass.build()) - .indent(" ") - .skipJavaLangImports(true) - .build() - ); - - // Write files to outputFolder - writeFiles( - filesToWrite, - outputFolder - ); - } -} diff --git a/demo/src/main/java/net/minestom/demo/entity/ChickenCreature.java b/demo/src/main/java/net/minestom/demo/entity/ChickenCreature.java index 6f241e422..14ea776f0 100644 --- a/demo/src/main/java/net/minestom/demo/entity/ChickenCreature.java +++ b/demo/src/main/java/net/minestom/demo/entity/ChickenCreature.java @@ -1,9 +1,9 @@ package net.minestom.demo.entity; -import net.minestom.server.attribute.Attribute; import net.minestom.server.entity.EntityCreature; import net.minestom.server.entity.EntityType; import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.minestom.server.entity.attribute.Attribute; import java.util.List; @@ -35,7 +35,7 @@ public class ChickenCreature extends EntityCreature { // .build() // ); - getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.1f); + getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.1); } @Override diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8230be930..cd19340c0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ metadata.format.version = "1.1" [versions] # Important dependencies -data = "1.20.4-rv4" +data = "24w13a-dev" adventure = "4.16.0" kotlin = "1.7.22" dependencyGetter = "v1.0.1" diff --git a/src/autogenerated/java/net/minestom/server/entity/EntityTypes.java b/src/autogenerated/java/net/minestom/server/entity/EntityTypes.java index 9c01f5253..0574ffcf2 100644 --- a/src/autogenerated/java/net/minestom/server/entity/EntityTypes.java +++ b/src/autogenerated/java/net/minestom/server/entity/EntityTypes.java @@ -9,6 +9,8 @@ interface EntityTypes { EntityType AREA_EFFECT_CLOUD = EntityTypeImpl.get("minecraft:area_effect_cloud"); + EntityType ARMADILLO = EntityTypeImpl.get("minecraft:armadillo"); + EntityType ARMOR_STAND = EntityTypeImpl.get("minecraft:armor_stand"); EntityType ARROW = EntityTypeImpl.get("minecraft:arrow"); @@ -25,8 +27,12 @@ interface EntityTypes { EntityType BOAT = EntityTypeImpl.get("minecraft:boat"); + EntityType BOGGED = EntityTypeImpl.get("minecraft:bogged"); + EntityType BREEZE = EntityTypeImpl.get("minecraft:breeze"); + EntityType BREEZE_WIND_CHARGE = EntityTypeImpl.get("minecraft:breeze_wind_charge"); + EntityType CAMEL = EntityTypeImpl.get("minecraft:camel"); EntityType CAT = EntityTypeImpl.get("minecraft:cat"); @@ -121,6 +127,8 @@ interface EntityTypes { EntityType ITEM_FRAME = EntityTypeImpl.get("minecraft:item_frame"); + EntityType OMINOUS_ITEM_SPAWNER = EntityTypeImpl.get("minecraft:ominous_item_spawner"); + EntityType FIREBALL = EntityTypeImpl.get("minecraft:fireball"); EntityType LEASH_KNOT = EntityTypeImpl.get("minecraft:leash_knot"); diff --git a/src/autogenerated/java/net/minestom/server/entity/attribute/Attributes.java b/src/autogenerated/java/net/minestom/server/entity/attribute/Attributes.java new file mode 100644 index 000000000..9f22bbe56 --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/entity/attribute/Attributes.java @@ -0,0 +1,51 @@ +package net.minestom.server.entity.attribute; + +/** + * Code autogenerated, do not edit! + */ +@SuppressWarnings("unused") +interface Attributes { + Attribute GENERIC_ARMOR = AttributeImpl.get("minecraft:generic.armor"); + + Attribute GENERIC_ARMOR_TOUGHNESS = AttributeImpl.get("minecraft:generic.armor_toughness"); + + Attribute GENERIC_ATTACK_DAMAGE = AttributeImpl.get("minecraft:generic.attack_damage"); + + Attribute GENERIC_ATTACK_KNOCKBACK = AttributeImpl.get("minecraft:generic.attack_knockback"); + + Attribute GENERIC_ATTACK_SPEED = AttributeImpl.get("minecraft:generic.attack_speed"); + + Attribute PLAYER_BLOCK_BREAK_SPEED = AttributeImpl.get("minecraft:player.block_break_speed"); + + Attribute PLAYER_BLOCK_INTERACTION_RANGE = AttributeImpl.get("minecraft:player.block_interaction_range"); + + Attribute PLAYER_ENTITY_INTERACTION_RANGE = AttributeImpl.get("minecraft:player.entity_interaction_range"); + + Attribute GENERIC_FALL_DAMAGE_MULTIPLIER = AttributeImpl.get("minecraft:generic.fall_damage_multiplier"); + + Attribute GENERIC_FLYING_SPEED = AttributeImpl.get("minecraft:generic.flying_speed"); + + Attribute GENERIC_FOLLOW_RANGE = AttributeImpl.get("minecraft:generic.follow_range"); + + Attribute GENERIC_GRAVITY = AttributeImpl.get("minecraft:generic.gravity"); + + Attribute GENERIC_JUMP_STRENGTH = AttributeImpl.get("minecraft:generic.jump_strength"); + + Attribute GENERIC_KNOCKBACK_RESISTANCE = AttributeImpl.get("minecraft:generic.knockback_resistance"); + + Attribute GENERIC_LUCK = AttributeImpl.get("minecraft:generic.luck"); + + Attribute GENERIC_MAX_ABSORPTION = AttributeImpl.get("minecraft:generic.max_absorption"); + + Attribute GENERIC_MAX_HEALTH = AttributeImpl.get("minecraft:generic.max_health"); + + Attribute GENERIC_MOVEMENT_SPEED = AttributeImpl.get("minecraft:generic.movement_speed"); + + Attribute GENERIC_SAFE_FALL_DISTANCE = AttributeImpl.get("minecraft:generic.safe_fall_distance"); + + Attribute GENERIC_SCALE = AttributeImpl.get("minecraft:generic.scale"); + + Attribute ZOMBIE_SPAWN_REINFORCEMENTS = AttributeImpl.get("minecraft:zombie.spawn_reinforcements"); + + Attribute GENERIC_STEP_HEIGHT = AttributeImpl.get("minecraft:generic.step_height"); +} diff --git a/src/autogenerated/java/net/minestom/server/entity/damage/DamageTypes.java b/src/autogenerated/java/net/minestom/server/entity/damage/DamageTypes.java index b1b11a6bf..2777f3608 100644 --- a/src/autogenerated/java/net/minestom/server/entity/damage/DamageTypes.java +++ b/src/autogenerated/java/net/minestom/server/entity/damage/DamageTypes.java @@ -33,6 +33,8 @@ interface DamageTypes { DamageType PLAYER_EXPLOSION = DamageTypeImpl.get("minecraft:player_explosion"); + DamageType SPIT = DamageTypeImpl.get("minecraft:spit"); + DamageType STING = DamageTypeImpl.get("minecraft:sting"); DamageType UNATTRIBUTED_FIREBALL = DamageTypeImpl.get("minecraft:unattributed_fireball"); diff --git a/src/autogenerated/java/net/minestom/server/instance/block/Blocks.java b/src/autogenerated/java/net/minestom/server/instance/block/Blocks.java index fc2a60332..974c15bb9 100644 --- a/src/autogenerated/java/net/minestom/server/instance/block/Blocks.java +++ b/src/autogenerated/java/net/minestom/server/instance/block/Blocks.java @@ -2120,4 +2120,8 @@ interface Blocks { Block CRAFTER = BlockImpl.get("minecraft:crafter"); Block TRIAL_SPAWNER = BlockImpl.get("minecraft:trial_spawner"); + + Block VAULT = BlockImpl.get("minecraft:vault"); + + Block HEAVY_CORE = BlockImpl.get("minecraft:heavy_core"); } diff --git a/src/autogenerated/java/net/minestom/server/item/Enchantments.java b/src/autogenerated/java/net/minestom/server/item/Enchantments.java index 1de0916b1..814705b2d 100644 --- a/src/autogenerated/java/net/minestom/server/item/Enchantments.java +++ b/src/autogenerated/java/net/minestom/server/item/Enchantments.java @@ -43,7 +43,7 @@ interface Enchantments { Enchantment LOOTING = EnchantmentImpl.get("minecraft:looting"); - Enchantment SWEEPING = EnchantmentImpl.get("minecraft:sweeping"); + Enchantment SWEEPING_EDGE = EnchantmentImpl.get("minecraft:sweeping_edge"); Enchantment EFFICIENCY = EnchantmentImpl.get("minecraft:efficiency"); @@ -79,6 +79,12 @@ interface Enchantments { Enchantment PIERCING = EnchantmentImpl.get("minecraft:piercing"); + Enchantment DENSITY = EnchantmentImpl.get("minecraft:density"); + + Enchantment BREACH = EnchantmentImpl.get("minecraft:breach"); + + Enchantment WIND_BURST = EnchantmentImpl.get("minecraft:wind_burst"); + Enchantment MENDING = EnchantmentImpl.get("minecraft:mending"); Enchantment VANISHING_CURSE = EnchantmentImpl.get("minecraft:vanishing_curse"); diff --git a/src/autogenerated/java/net/minestom/server/item/Materials.java b/src/autogenerated/java/net/minestom/server/item/Materials.java index 17aab6094..622f5a00e 100644 --- a/src/autogenerated/java/net/minestom/server/item/Materials.java +++ b/src/autogenerated/java/net/minestom/server/item/Materials.java @@ -175,6 +175,8 @@ interface Materials { Material RAW_GOLD_BLOCK = MaterialImpl.get("minecraft:raw_gold_block"); + Material HEAVY_CORE = MaterialImpl.get("minecraft:heavy_core"); + Material AMETHYST_BLOCK = MaterialImpl.get("minecraft:amethyst_block"); Material BUDDING_AMETHYST = MaterialImpl.get("minecraft:budding_amethyst"); @@ -1593,7 +1595,11 @@ interface Materials { Material TURTLE_HELMET = MaterialImpl.get("minecraft:turtle_helmet"); - Material SCUTE = MaterialImpl.get("minecraft:scute"); + Material TURTLE_SCUTE = MaterialImpl.get("minecraft:turtle_scute"); + + Material ARMADILLO_SCUTE = MaterialImpl.get("minecraft:armadillo_scute"); + + Material WOLF_ARMOR = MaterialImpl.get("minecraft:wolf_armor"); Material FLINT_AND_STEEL = MaterialImpl.get("minecraft:flint_and_steel"); @@ -2015,6 +2021,8 @@ interface Materials { Material GLISTERING_MELON_SLICE = MaterialImpl.get("minecraft:glistering_melon_slice"); + Material ARMADILLO_SPAWN_EGG = MaterialImpl.get("minecraft:armadillo_spawn_egg"); + Material ALLAY_SPAWN_EGG = MaterialImpl.get("minecraft:allay_spawn_egg"); Material AXOLOTL_SPAWN_EGG = MaterialImpl.get("minecraft:axolotl_spawn_egg"); @@ -2025,6 +2033,8 @@ interface Materials { Material BLAZE_SPAWN_EGG = MaterialImpl.get("minecraft:blaze_spawn_egg"); + Material BOGGED_SPAWN_EGG = MaterialImpl.get("minecraft:bogged_spawn_egg"); + Material BREEZE_SPAWN_EGG = MaterialImpl.get("minecraft:breeze_spawn_egg"); Material CAT_SPAWN_EGG = MaterialImpl.get("minecraft:cat_spawn_egg"); @@ -2175,10 +2185,14 @@ interface Materials { Material FIRE_CHARGE = MaterialImpl.get("minecraft:fire_charge"); + Material WIND_CHARGE = MaterialImpl.get("minecraft:wind_charge"); + Material WRITABLE_BOOK = MaterialImpl.get("minecraft:writable_book"); Material WRITTEN_BOOK = MaterialImpl.get("minecraft:written_book"); + Material MACE = MaterialImpl.get("minecraft:mace"); + Material ITEM_FRAME = MaterialImpl.get("minecraft:item_frame"); Material GLOW_ITEM_FRAME = MaterialImpl.get("minecraft:glow_item_frame"); @@ -2387,6 +2401,10 @@ interface Materials { Material PIGLIN_BANNER_PATTERN = MaterialImpl.get("minecraft:piglin_banner_pattern"); + Material FLOW_BANNER_PATTERN = MaterialImpl.get("minecraft:flow_banner_pattern"); + + Material GUSTER_BANNER_PATTERN = MaterialImpl.get("minecraft:guster_banner_pattern"); + Material GOAT_HORN = MaterialImpl.get("minecraft:goat_horn"); Material COMPOSTER = MaterialImpl.get("minecraft:composter"); @@ -2553,6 +2571,10 @@ interface Materials { Material HOST_ARMOR_TRIM_SMITHING_TEMPLATE = MaterialImpl.get("minecraft:host_armor_trim_smithing_template"); + Material FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = MaterialImpl.get("minecraft:flow_armor_trim_smithing_template"); + + Material BOLT_ARMOR_TRIM_SMITHING_TEMPLATE = MaterialImpl.get("minecraft:bolt_armor_trim_smithing_template"); + Material ANGLER_POTTERY_SHERD = MaterialImpl.get("minecraft:angler_pottery_sherd"); Material ARCHER_POTTERY_SHERD = MaterialImpl.get("minecraft:archer_pottery_sherd"); @@ -2569,8 +2591,12 @@ interface Materials { Material EXPLORER_POTTERY_SHERD = MaterialImpl.get("minecraft:explorer_pottery_sherd"); + Material FLOW_POTTERY_SHERD = MaterialImpl.get("minecraft:flow_pottery_sherd"); + Material FRIEND_POTTERY_SHERD = MaterialImpl.get("minecraft:friend_pottery_sherd"); + Material GUSTER_POTTERY_SHERD = MaterialImpl.get("minecraft:guster_pottery_sherd"); + Material HEART_POTTERY_SHERD = MaterialImpl.get("minecraft:heart_pottery_sherd"); Material HEARTBREAK_POTTERY_SHERD = MaterialImpl.get("minecraft:heartbreak_pottery_sherd"); @@ -2585,6 +2611,8 @@ interface Materials { Material PRIZE_POTTERY_SHERD = MaterialImpl.get("minecraft:prize_pottery_sherd"); + Material SCRAPE_POTTERY_SHERD = MaterialImpl.get("minecraft:scrape_pottery_sherd"); + Material SHEAF_POTTERY_SHERD = MaterialImpl.get("minecraft:sheaf_pottery_sherd"); Material SHELTER_POTTERY_SHERD = MaterialImpl.get("minecraft:shelter_pottery_sherd"); @@ -2628,4 +2656,12 @@ interface Materials { Material TRIAL_SPAWNER = MaterialImpl.get("minecraft:trial_spawner"); Material TRIAL_KEY = MaterialImpl.get("minecraft:trial_key"); + + Material OMINOUS_TRIAL_KEY = MaterialImpl.get("minecraft:ominous_trial_key"); + + Material VAULT = MaterialImpl.get("minecraft:vault"); + + Material OMINOUS_BOTTLE = MaterialImpl.get("minecraft:ominous_bottle"); + + Material BREEZE_ROD = MaterialImpl.get("minecraft:breeze_rod"); } diff --git a/src/autogenerated/java/net/minestom/server/particle/Particles.java b/src/autogenerated/java/net/minestom/server/particle/Particles.java index 691280c43..a25a661c0 100644 --- a/src/autogenerated/java/net/minestom/server/particle/Particles.java +++ b/src/autogenerated/java/net/minestom/server/particle/Particles.java @@ -5,8 +5,6 @@ package net.minestom.server.particle; */ @SuppressWarnings("unused") interface Particles { - Particle AMBIENT_ENTITY_EFFECT = ParticleImpl.get("minecraft:ambient_entity_effect"); - Particle ANGRY_VILLAGER = ParticleImpl.get("minecraft:angry_villager"); Particle BLOCK = ParticleImpl.get("minecraft:block"); @@ -55,7 +53,11 @@ interface Particles { Particle GUST = ParticleImpl.get("minecraft:gust"); - Particle GUST_EMITTER = ParticleImpl.get("minecraft:gust_emitter"); + Particle SMALL_GUST = ParticleImpl.get("minecraft:small_gust"); + + Particle GUST_EMITTER_LARGE = ParticleImpl.get("minecraft:gust_emitter_large"); + + Particle GUST_EMITTER_SMALL = ParticleImpl.get("minecraft:gust_emitter_small"); Particle SONIC_BOOM = ParticleImpl.get("minecraft:sonic_boom"); @@ -67,6 +69,8 @@ interface Particles { Particle FLAME = ParticleImpl.get("minecraft:flame"); + Particle INFESTED = ParticleImpl.get("minecraft:infested"); + Particle CHERRY_LEAVES = ParticleImpl.get("minecraft:cherry_leaves"); Particle SCULK_SOUL = ParticleImpl.get("minecraft:sculk_soul"); @@ -95,6 +99,8 @@ interface Particles { Particle ITEM_SLIME = ParticleImpl.get("minecraft:item_slime"); + Particle ITEM_COBWEB = ParticleImpl.get("minecraft:item_cobweb"); + Particle ITEM_SNOWBALL = ParticleImpl.get("minecraft:item_snowball"); Particle LARGE_SMOKE = ParticleImpl.get("minecraft:large_smoke"); @@ -203,7 +209,17 @@ interface Particles { Particle DUST_PLUME = ParticleImpl.get("minecraft:dust_plume"); - Particle GUST_DUST = ParticleImpl.get("minecraft:gust_dust"); - Particle TRIAL_SPAWNER_DETECTION = ParticleImpl.get("minecraft:trial_spawner_detection"); + + Particle TRIAL_SPAWNER_DETECTION_OMINOUS = ParticleImpl.get("minecraft:trial_spawner_detection_ominous"); + + Particle VAULT_CONNECTION = ParticleImpl.get("minecraft:vault_connection"); + + Particle DUST_PILLAR = ParticleImpl.get("minecraft:dust_pillar"); + + Particle OMINOUS_SPAWNING = ParticleImpl.get("minecraft:ominous_spawning"); + + Particle RAID_OMEN = ParticleImpl.get("minecraft:raid_omen"); + + Particle TRIAL_OMEN = ParticleImpl.get("minecraft:trial_omen"); } diff --git a/src/autogenerated/java/net/minestom/server/potion/PotionEffects.java b/src/autogenerated/java/net/minestom/server/potion/PotionEffects.java index 00189dc46..6116a8692 100644 --- a/src/autogenerated/java/net/minestom/server/potion/PotionEffects.java +++ b/src/autogenerated/java/net/minestom/server/potion/PotionEffects.java @@ -70,4 +70,16 @@ interface PotionEffects { PotionEffect HERO_OF_THE_VILLAGE = PotionEffectImpl.get("minecraft:hero_of_the_village"); PotionEffect DARKNESS = PotionEffectImpl.get("minecraft:darkness"); + + PotionEffect TRIAL_OMEN = PotionEffectImpl.get("minecraft:trial_omen"); + + PotionEffect RAID_OMEN = PotionEffectImpl.get("minecraft:raid_omen"); + + PotionEffect WIND_CHARGED = PotionEffectImpl.get("minecraft:wind_charged"); + + PotionEffect WEAVING = PotionEffectImpl.get("minecraft:weaving"); + + PotionEffect OOZING = PotionEffectImpl.get("minecraft:oozing"); + + PotionEffect INFESTED = PotionEffectImpl.get("minecraft:infested"); } diff --git a/src/autogenerated/java/net/minestom/server/potion/PotionTypes.java b/src/autogenerated/java/net/minestom/server/potion/PotionTypes.java index 91430a100..fc078487d 100644 --- a/src/autogenerated/java/net/minestom/server/potion/PotionTypes.java +++ b/src/autogenerated/java/net/minestom/server/potion/PotionTypes.java @@ -5,8 +5,6 @@ package net.minestom.server.potion; */ @SuppressWarnings("unused") interface PotionTypes { - PotionType EMPTY = PotionTypeImpl.get("minecraft:empty"); - PotionType WATER = PotionTypeImpl.get("minecraft:water"); PotionType MUNDANE = PotionTypeImpl.get("minecraft:mundane"); @@ -90,4 +88,12 @@ interface PotionTypes { PotionType SLOW_FALLING = PotionTypeImpl.get("minecraft:slow_falling"); PotionType LONG_SLOW_FALLING = PotionTypeImpl.get("minecraft:long_slow_falling"); + + PotionType WIND_CHARGED = PotionTypeImpl.get("minecraft:wind_charged"); + + PotionType WEAVING = PotionTypeImpl.get("minecraft:weaving"); + + PotionType OOZING = PotionTypeImpl.get("minecraft:oozing"); + + PotionType INFESTED = PotionTypeImpl.get("minecraft:infested"); } diff --git a/src/autogenerated/java/net/minestom/server/sound/SoundEvents.java b/src/autogenerated/java/net/minestom/server/sound/SoundEvents.java index bd1d0287f..61da7da29 100644 --- a/src/autogenerated/java/net/minestom/server/sound/SoundEvents.java +++ b/src/autogenerated/java/net/minestom/server/sound/SoundEvents.java @@ -113,6 +113,32 @@ interface SoundEvents { SoundEvent BLOCK_ANVIL_USE = SoundEventImpl.get("minecraft:block.anvil.use"); + SoundEvent ENTITY_ARMADILLO_EAT = SoundEventImpl.get("minecraft:entity.armadillo.eat"); + + SoundEvent ENTITY_ARMADILLO_HURT = SoundEventImpl.get("minecraft:entity.armadillo.hurt"); + + SoundEvent ENTITY_ARMADILLO_HURT_REDUCED = SoundEventImpl.get("minecraft:entity.armadillo.hurt_reduced"); + + SoundEvent ENTITY_ARMADILLO_AMBIENT = SoundEventImpl.get("minecraft:entity.armadillo.ambient"); + + SoundEvent ENTITY_ARMADILLO_STEP = SoundEventImpl.get("minecraft:entity.armadillo.step"); + + SoundEvent ENTITY_ARMADILLO_DEATH = SoundEventImpl.get("minecraft:entity.armadillo.death"); + + SoundEvent ENTITY_ARMADILLO_ROLL = SoundEventImpl.get("minecraft:entity.armadillo.roll"); + + SoundEvent ENTITY_ARMADILLO_LAND = SoundEventImpl.get("minecraft:entity.armadillo.land"); + + SoundEvent ENTITY_ARMADILLO_SCUTE_DROP = SoundEventImpl.get("minecraft:entity.armadillo.scute_drop"); + + SoundEvent ENTITY_ARMADILLO_UNROLL_FINISH = SoundEventImpl.get("minecraft:entity.armadillo.unroll_finish"); + + SoundEvent ENTITY_ARMADILLO_PEEK = SoundEventImpl.get("minecraft:entity.armadillo.peek"); + + SoundEvent ENTITY_ARMADILLO_UNROLL_START = SoundEventImpl.get("minecraft:entity.armadillo.unroll_start"); + + SoundEvent ENTITY_ARMADILLO_BRUSH = SoundEventImpl.get("minecraft:entity.armadillo.brush"); + SoundEvent ITEM_ARMOR_EQUIP_CHAIN = SoundEventImpl.get("minecraft:item.armor.equip_chain"); SoundEvent ITEM_ARMOR_EQUIP_DIAMOND = SoundEventImpl.get("minecraft:item.armor.equip_diamond"); @@ -131,6 +157,10 @@ interface SoundEvents { SoundEvent ITEM_ARMOR_EQUIP_TURTLE = SoundEventImpl.get("minecraft:item.armor.equip_turtle"); + SoundEvent ITEM_ARMOR_EQUIP_WOLF = SoundEventImpl.get("minecraft:item.armor.equip_wolf"); + + SoundEvent ITEM_ARMOR_UNEQUIP_WOLF = SoundEventImpl.get("minecraft:item.armor.unequip_wolf"); + SoundEvent ENTITY_ARMOR_STAND_BREAK = SoundEventImpl.get("minecraft:entity.armor_stand.break"); SoundEvent ENTITY_ARMOR_STAND_FALL = SoundEventImpl.get("minecraft:entity.armor_stand.fall"); @@ -313,6 +343,16 @@ interface SoundEvents { SoundEvent ENTITY_BOAT_PADDLE_WATER = SoundEventImpl.get("minecraft:entity.boat.paddle_water"); + SoundEvent ENTITY_BOGGED_AMBIENT = SoundEventImpl.get("minecraft:entity.bogged.ambient"); + + SoundEvent ENTITY_BOGGED_DEATH = SoundEventImpl.get("minecraft:entity.bogged.death"); + + SoundEvent ENTITY_BOGGED_HURT = SoundEventImpl.get("minecraft:entity.bogged.hurt"); + + SoundEvent ENTITY_BOGGED_SHEAR = SoundEventImpl.get("minecraft:entity.bogged.shear"); + + SoundEvent ENTITY_BOGGED_STEP = SoundEventImpl.get("minecraft:entity.bogged.step"); + SoundEvent BLOCK_BONE_BLOCK_BREAK = SoundEventImpl.get("minecraft:block.bone_block.break"); SoundEvent BLOCK_BONE_BLOCK_FALL = SoundEventImpl.get("minecraft:block.bone_block.fall"); @@ -337,6 +377,10 @@ interface SoundEvents { SoundEvent ITEM_BOTTLE_FILL_DRAGONBREATH = SoundEventImpl.get("minecraft:item.bottle.fill_dragonbreath"); + SoundEvent ENTITY_BREEZE_CHARGE = SoundEventImpl.get("minecraft:entity.breeze.charge"); + + SoundEvent ENTITY_BREEZE_DEFLECT = SoundEventImpl.get("minecraft:entity.breeze.deflect"); + SoundEvent ENTITY_BREEZE_INHALE = SoundEventImpl.get("minecraft:entity.breeze.inhale"); SoundEvent ENTITY_BREEZE_IDLE_GROUND = SoundEventImpl.get("minecraft:entity.breeze.idle_ground"); @@ -355,6 +399,10 @@ interface SoundEvents { SoundEvent ENTITY_BREEZE_HURT = SoundEventImpl.get("minecraft:entity.breeze.hurt"); + SoundEvent ENTITY_BREEZE_WHIRL = SoundEventImpl.get("minecraft:entity.breeze.whirl"); + + SoundEvent ENTITY_BREEZE_WIND_BURST = SoundEventImpl.get("minecraft:entity.breeze.wind_burst"); + SoundEvent BLOCK_BREWING_STAND_BREW = SoundEventImpl.get("minecraft:block.brewing_stand.brew"); SoundEvent ITEM_BRUSH_BRUSHING_GENERIC = SoundEventImpl.get("minecraft:item.brush.brushing.generic"); @@ -597,6 +645,16 @@ interface SoundEvents { SoundEvent ITEM_CHORUS_FRUIT_TELEPORT = SoundEventImpl.get("minecraft:item.chorus_fruit.teleport"); + SoundEvent BLOCK_COBWEB_BREAK = SoundEventImpl.get("minecraft:block.cobweb.break"); + + SoundEvent BLOCK_COBWEB_STEP = SoundEventImpl.get("minecraft:block.cobweb.step"); + + SoundEvent BLOCK_COBWEB_PLACE = SoundEventImpl.get("minecraft:block.cobweb.place"); + + SoundEvent BLOCK_COBWEB_HIT = SoundEventImpl.get("minecraft:block.cobweb.hit"); + + SoundEvent BLOCK_COBWEB_FALL = SoundEventImpl.get("minecraft:block.cobweb.fall"); + SoundEvent ENTITY_COD_AMBIENT = SoundEventImpl.get("minecraft:entity.cod.ambient"); SoundEvent ENTITY_COD_DEATH = SoundEventImpl.get("minecraft:entity.cod.death"); @@ -801,6 +859,8 @@ interface SoundEvents { SoundEvent ENTITY_DONKEY_HURT = SoundEventImpl.get("minecraft:entity.donkey.hurt"); + SoundEvent ENTITY_DONKEY_JUMP = SoundEventImpl.get("minecraft:entity.donkey.jump"); + SoundEvent BLOCK_DRIPSTONE_BLOCK_BREAK = SoundEventImpl.get("minecraft:block.dripstone_block.break"); SoundEvent BLOCK_DRIPSTONE_BLOCK_STEP = SoundEventImpl.get("minecraft:block.dripstone_block.step"); @@ -1261,6 +1321,16 @@ interface SoundEvents { SoundEvent BLOCK_HANGING_SIGN_PLACE = SoundEventImpl.get("minecraft:block.hanging_sign.place"); + SoundEvent BLOCK_HEAVY_CORE_BREAK = SoundEventImpl.get("minecraft:block.heavy_core.break"); + + SoundEvent BLOCK_HEAVY_CORE_FALL = SoundEventImpl.get("minecraft:block.heavy_core.fall"); + + SoundEvent BLOCK_HEAVY_CORE_HIT = SoundEventImpl.get("minecraft:block.heavy_core.hit"); + + SoundEvent BLOCK_HEAVY_CORE_PLACE = SoundEventImpl.get("minecraft:block.heavy_core.place"); + + SoundEvent BLOCK_HEAVY_CORE_STEP = SoundEventImpl.get("minecraft:block.heavy_core.step"); + SoundEvent BLOCK_NETHER_WOOD_HANGING_SIGN_STEP = SoundEventImpl.get("minecraft:block.nether_wood_hanging_sign.step"); SoundEvent BLOCK_NETHER_WOOD_HANGING_SIGN_BREAK = SoundEventImpl.get("minecraft:block.nether_wood_hanging_sign.break"); @@ -1293,10 +1363,20 @@ interface SoundEvents { SoundEvent BLOCK_TRIAL_SPAWNER_SPAWN_MOB = SoundEventImpl.get("minecraft:block.trial_spawner.spawn_mob"); + SoundEvent BLOCK_TRIAL_SPAWNER_ABOUT_TO_SPAWN_ITEM = SoundEventImpl.get("minecraft:block.trial_spawner.about_to_spawn_item"); + + SoundEvent BLOCK_TRIAL_SPAWNER_SPAWN_ITEM = SoundEventImpl.get("minecraft:block.trial_spawner.spawn_item"); + + SoundEvent BLOCK_TRIAL_SPAWNER_SPAWN_ITEM_BEGIN = SoundEventImpl.get("minecraft:block.trial_spawner.spawn_item_begin"); + SoundEvent BLOCK_TRIAL_SPAWNER_DETECT_PLAYER = SoundEventImpl.get("minecraft:block.trial_spawner.detect_player"); + SoundEvent BLOCK_TRIAL_SPAWNER_CHARGE_ACTIVATE = SoundEventImpl.get("minecraft:block.trial_spawner.charge_activate"); + SoundEvent BLOCK_TRIAL_SPAWNER_AMBIENT = SoundEventImpl.get("minecraft:block.trial_spawner.ambient"); + SoundEvent BLOCK_TRIAL_SPAWNER_AMBIENT_CHARGED = SoundEventImpl.get("minecraft:block.trial_spawner.ambient_charged"); + SoundEvent BLOCK_TRIAL_SPAWNER_OPEN_SHUTTER = SoundEventImpl.get("minecraft:block.trial_spawner.open_shutter"); SoundEvent BLOCK_TRIAL_SPAWNER_CLOSE_SHUTTER = SoundEventImpl.get("minecraft:block.trial_spawner.close_shutter"); @@ -1525,6 +1605,12 @@ interface SoundEvents { SoundEvent ITEM_LODESTONE_COMPASS_LOCK = SoundEventImpl.get("minecraft:item.lodestone_compass.lock"); + SoundEvent ITEM_MACE_SMASH_AIR = SoundEventImpl.get("minecraft:item.mace.smash_air"); + + SoundEvent ITEM_MACE_SMASH_GROUND = SoundEventImpl.get("minecraft:item.mace.smash_ground"); + + SoundEvent ITEM_MACE_SMASH_GROUND_HEAVY = SoundEventImpl.get("minecraft:item.mace.smash_ground_heavy"); + SoundEvent ENTITY_MAGMA_CUBE_DEATH = SoundEventImpl.get("minecraft:entity.magma_cube.death"); SoundEvent ENTITY_MAGMA_CUBE_HURT = SoundEventImpl.get("minecraft:entity.magma_cube.hurt"); @@ -1653,6 +1739,8 @@ interface SoundEvents { SoundEvent ENTITY_MULE_HURT = SoundEventImpl.get("minecraft:entity.mule.hurt"); + SoundEvent ENTITY_MULE_JUMP = SoundEventImpl.get("minecraft:entity.mule.jump"); + SoundEvent MUSIC_CREATIVE = SoundEventImpl.get("minecraft:music.creative"); SoundEvent MUSIC_CREDITS = SoundEventImpl.get("minecraft:music.credits"); @@ -1933,6 +2021,8 @@ interface SoundEvents { SoundEvent ENTITY_OCELOT_DEATH = SoundEventImpl.get("minecraft:entity.ocelot.death"); + SoundEvent ITEM_OMINOUS_BOTTLE_DISPOSE = SoundEventImpl.get("minecraft:item.ominous_bottle.dispose"); + SoundEvent ENTITY_PAINTING_BREAK = SoundEventImpl.get("minecraft:entity.painting.break"); SoundEvent ENTITY_PAINTING_PLACE = SoundEventImpl.get("minecraft:entity.painting.place"); @@ -1971,6 +2061,8 @@ interface SoundEvents { SoundEvent ENTITY_PARROT_IMITATE_BLAZE = SoundEventImpl.get("minecraft:entity.parrot.imitate.blaze"); + SoundEvent ENTITY_PARROT_IMITATE_BOGGED = SoundEventImpl.get("minecraft:entity.parrot.imitate.bogged"); + SoundEvent ENTITY_PARROT_IMITATE_BREEZE = SoundEventImpl.get("minecraft:entity.parrot.imitate.breeze"); SoundEvent ENTITY_PARROT_IMITATE_CREEPER = SoundEventImpl.get("minecraft:entity.parrot.imitate.creeper"); @@ -2779,6 +2871,32 @@ interface SoundEvents { SoundEvent UI_TOAST_OUT = SoundEventImpl.get("minecraft:ui.toast.out"); + SoundEvent BLOCK_VAULT_ACTIVATE = SoundEventImpl.get("minecraft:block.vault.activate"); + + SoundEvent BLOCK_VAULT_AMBIENT = SoundEventImpl.get("minecraft:block.vault.ambient"); + + SoundEvent BLOCK_VAULT_BREAK = SoundEventImpl.get("minecraft:block.vault.break"); + + SoundEvent BLOCK_VAULT_CLOSE_SHUTTER = SoundEventImpl.get("minecraft:block.vault.close_shutter"); + + SoundEvent BLOCK_VAULT_DEACTIVATE = SoundEventImpl.get("minecraft:block.vault.deactivate"); + + SoundEvent BLOCK_VAULT_EJECT_ITEM = SoundEventImpl.get("minecraft:block.vault.eject_item"); + + SoundEvent BLOCK_VAULT_FALL = SoundEventImpl.get("minecraft:block.vault.fall"); + + SoundEvent BLOCK_VAULT_HIT = SoundEventImpl.get("minecraft:block.vault.hit"); + + SoundEvent BLOCK_VAULT_INSERT_ITEM = SoundEventImpl.get("minecraft:block.vault.insert_item"); + + SoundEvent BLOCK_VAULT_INSERT_ITEM_FAIL = SoundEventImpl.get("minecraft:block.vault.insert_item_fail"); + + SoundEvent BLOCK_VAULT_OPEN_SHUTTER = SoundEventImpl.get("minecraft:block.vault.open_shutter"); + + SoundEvent BLOCK_VAULT_PLACE = SoundEventImpl.get("minecraft:block.vault.place"); + + SoundEvent BLOCK_VAULT_STEP = SoundEventImpl.get("minecraft:block.vault.step"); + SoundEvent ENTITY_VEX_AMBIENT = SoundEventImpl.get("minecraft:entity.vex.ambient"); SoundEvent ENTITY_VEX_CHARGE = SoundEventImpl.get("minecraft:entity.vex.charge"); @@ -2929,6 +3047,8 @@ interface SoundEvents { SoundEvent BLOCK_WET_SPONGE_BREAK = SoundEventImpl.get("minecraft:block.wet_sponge.break"); + SoundEvent BLOCK_WET_SPONGE_DRIES = SoundEventImpl.get("minecraft:block.wet_sponge.dries"); + SoundEvent BLOCK_WET_SPONGE_FALL = SoundEventImpl.get("minecraft:block.wet_sponge.fall"); SoundEvent BLOCK_WET_SPONGE_HIT = SoundEventImpl.get("minecraft:block.wet_sponge.hit"); @@ -2937,7 +3057,9 @@ interface SoundEvents { SoundEvent BLOCK_WET_SPONGE_STEP = SoundEventImpl.get("minecraft:block.wet_sponge.step"); - SoundEvent ENTITY_GENERIC_WIND_BURST = SoundEventImpl.get("minecraft:entity.generic.wind_burst"); + SoundEvent ENTITY_WIND_CHARGE_WIND_BURST = SoundEventImpl.get("minecraft:entity.wind_charge.wind_burst"); + + SoundEvent ENTITY_WIND_CHARGE_THROW = SoundEventImpl.get("minecraft:entity.wind_charge.throw"); SoundEvent ENTITY_WITCH_AMBIENT = SoundEventImpl.get("minecraft:entity.witch.ambient"); @@ -2971,6 +3093,14 @@ interface SoundEvents { SoundEvent ENTITY_WITHER_SPAWN = SoundEventImpl.get("minecraft:entity.wither.spawn"); + SoundEvent ITEM_WOLF_ARMOR_BREAK = SoundEventImpl.get("minecraft:item.wolf_armor.break"); + + SoundEvent ITEM_WOLF_ARMOR_CRACK = SoundEventImpl.get("minecraft:item.wolf_armor.crack"); + + SoundEvent ITEM_WOLF_ARMOR_DAMAGE = SoundEventImpl.get("minecraft:item.wolf_armor.damage"); + + SoundEvent ITEM_WOLF_ARMOR_REPAIR = SoundEventImpl.get("minecraft:item.wolf_armor.repair"); + SoundEvent ENTITY_WOLF_AMBIENT = SoundEventImpl.get("minecraft:entity.wolf.ambient"); SoundEvent ENTITY_WOLF_DEATH = SoundEventImpl.get("minecraft:entity.wolf.death"); @@ -3082,4 +3212,10 @@ interface SoundEvents { SoundEvent ENTITY_ZOMBIE_VILLAGER_HURT = SoundEventImpl.get("minecraft:entity.zombie_villager.hurt"); SoundEvent ENTITY_ZOMBIE_VILLAGER_STEP = SoundEventImpl.get("minecraft:entity.zombie_villager.step"); + + SoundEvent EVENT_MOB_EFFECT_BAD_OMEN = SoundEventImpl.get("minecraft:event.mob_effect.bad_omen"); + + SoundEvent EVENT_MOB_EFFECT_TRIAL_OMEN = SoundEventImpl.get("minecraft:event.mob_effect.trial_omen"); + + SoundEvent EVENT_MOB_EFFECT_RAID_OMEN = SoundEventImpl.get("minecraft:event.mob_effect.raid_omen"); } diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index d8ffa9602..98eae2cfb 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -44,8 +44,8 @@ public final class MinecraftServer { public static final ComponentLogger LOGGER = ComponentLogger.logger(MinecraftServer.class); - public static final String VERSION_NAME = "1.20.4"; - public static final int PROTOCOL_VERSION = 765; + public static final String VERSION_NAME = "24w14a"; + public static final int PROTOCOL_VERSION = 1073742008; // Threads public static final String THREAD_NAME_BENCHMARK = "Ms-Benchmark"; diff --git a/src/main/java/net/minestom/server/attribute/Attribute.java b/src/main/java/net/minestom/server/attribute/Attribute.java deleted file mode 100644 index ed97a493c..000000000 --- a/src/main/java/net/minestom/server/attribute/Attribute.java +++ /dev/null @@ -1,66 +0,0 @@ -package net.minestom.server.attribute; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Represents a {@link net.minestom.server.entity.LivingEntity living entity} attribute. - */ -public record Attribute(String key, float defaultValue, float maxValue) { - private static final Map ATTRIBUTES = new ConcurrentHashMap<>(); - - public static final Attribute MAX_HEALTH = (new Attribute("generic.max_health", 20, 1024)).register(); - public static final Attribute FOLLOW_RANGE = (new Attribute("generic.follow_range", 32, 2048)).register(); - public static final Attribute KNOCKBACK_RESISTANCE = (new Attribute("generic.knockback_resistance", 0, 1)).register(); - public static final Attribute MOVEMENT_SPEED = (new Attribute("generic.movement_speed", 0.25f, 1024)).register(); - public static final Attribute ATTACK_DAMAGE = (new Attribute("generic.attack_damage", 2, 2048)).register(); - public static final Attribute ATTACK_SPEED = (new Attribute("generic.attack_speed", 4, 1024)).register(); - public static final Attribute FLYING_SPEED = (new Attribute("generic.flying_speed", 0.4f, 1024)).register(); - public static final Attribute ARMOR = (new Attribute("generic.armor", 0, 30)).register(); - public static final Attribute ARMOR_TOUGHNESS = (new Attribute("generic.armor_toughness", 0, 20)).register(); - public static final Attribute ATTACK_KNOCKBACK = (new Attribute("generic.attack_knockback", 0, 5)).register(); - public static final Attribute LUCK = (new Attribute("generic.luck", 0, 1024)).register(); - public static final Attribute HORSE_JUMP_STRENGTH = (new Attribute("horse.jump_strength", 0.7f, 2)).register(); - public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = (new Attribute("zombie.spawn_reinforcements", 0, 1)).register(); - - public Attribute { - if (defaultValue > maxValue) { - throw new IllegalArgumentException("Default value cannot be greater than the maximum allowed"); - } - } - - /** - * Register this attribute. - * - * @return this attribute - * @see #fromKey(String) - * @see #values() - */ - public @NotNull Attribute register() { - ATTRIBUTES.put(key, this); - return this; - } - - /** - * Retrieves an attribute by its key. - * - * @param key the key of the attribute - * @return the attribute for the key or null if not any - */ - public static @Nullable Attribute fromKey(@NotNull String key) { - return ATTRIBUTES.get(key); - } - - /** - * Retrieves all registered attributes. - * - * @return an array containing all registered attributes - */ - public static @NotNull Collection<@NotNull Attribute> values() { - return ATTRIBUTES.values(); - } -} diff --git a/src/main/java/net/minestom/server/entity/LivingEntity.java b/src/main/java/net/minestom/server/entity/LivingEntity.java index 368f91882..8e3c69c39 100644 --- a/src/main/java/net/minestom/server/entity/LivingEntity.java +++ b/src/main/java/net/minestom/server/entity/LivingEntity.java @@ -1,11 +1,11 @@ package net.minestom.server.entity; import net.kyori.adventure.sound.Sound.Source; -import net.minestom.server.attribute.Attribute; -import net.minestom.server.attribute.AttributeInstance; import net.minestom.server.collision.BoundingBox; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Vec; +import net.minestom.server.entity.attribute.Attribute; +import net.minestom.server.entity.attribute.AttributeInstance; import net.minestom.server.entity.damage.Damage; import net.minestom.server.entity.damage.DamageType; import net.minestom.server.entity.metadata.LivingEntityMeta; @@ -22,7 +22,7 @@ import net.minestom.server.network.ConnectionState; import net.minestom.server.network.packet.server.LazyPacket; import net.minestom.server.network.packet.server.play.CollectItemPacket; import net.minestom.server.network.packet.server.play.EntityAnimationPacket; -import net.minestom.server.network.packet.server.play.EntityPropertiesPacket; +import net.minestom.server.network.packet.server.play.EntityAttributesPacket; import net.minestom.server.network.packet.server.play.SoundEffectPacket; import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.scoreboard.Team; @@ -419,21 +419,21 @@ public class LivingEntity extends Entity implements EquipmentHandler { } /** - * Gets the entity max health from {@link #getAttributeValue(Attribute)} {@link Attribute#MAX_HEALTH}. + * Gets the entity max health from {@link #getAttributeValue(Attribute)} {@link Attribute#GENERIC_MAX_HEALTH}. * * @return the entity max health */ public float getMaxHealth() { - return getAttributeValue(Attribute.MAX_HEALTH); + return (float) getAttributeValue(Attribute.GENERIC_MAX_HEALTH); } /** * Sets the heal of the entity as its max health. *

- * Retrieved from {@link #getAttributeValue(Attribute)} with the attribute {@link Attribute#MAX_HEALTH}. + * Retrieved from {@link #getAttributeValue(Attribute)} with the attribute {@link Attribute#GENERIC_MAX_HEALTH}. */ public void heal() { - setHealth(getAttributeValue(Attribute.MAX_HEALTH)); + setHealth((float) getAttributeValue(Attribute.GENERIC_MAX_HEALTH)); } /** @@ -443,7 +443,7 @@ public class LivingEntity extends Entity implements EquipmentHandler { * @return the attribute instance */ public @NotNull AttributeInstance getAttribute(@NotNull Attribute attribute) { - return attributeModifiers.computeIfAbsent(attribute.key(), + return attributeModifiers.computeIfAbsent(attribute.name(), s -> new AttributeInstance(attribute, this::onAttributeChanged)); } @@ -459,7 +459,7 @@ public class LivingEntity extends Entity implements EquipmentHandler { // connection null during Player initialization (due to #super call) self = playerConnection != null && playerConnection.getConnectionState() == ConnectionState.PLAY; } - EntityPropertiesPacket propertiesPacket = new EntityPropertiesPacket(getEntityId(), List.of(attributeInstance)); + EntityAttributesPacket propertiesPacket = new EntityAttributesPacket(getEntityId(), List.of(attributeInstance)); if (self) { sendPacketToViewersAndSelf(propertiesPacket); } else { @@ -473,8 +473,8 @@ public class LivingEntity extends Entity implements EquipmentHandler { * @param attribute the attribute value to get * @return the attribute value */ - public float getAttributeValue(@NotNull Attribute attribute) { - AttributeInstance instance = attributeModifiers.get(attribute.key()); + public double getAttributeValue(@NotNull Attribute attribute) { + AttributeInstance instance = attributeModifiers.get(attribute.name()); return (instance != null) ? instance.getValue() : attribute.defaultValue(); } @@ -566,12 +566,12 @@ public class LivingEntity extends Entity implements EquipmentHandler { } /** - * Gets an {@link EntityPropertiesPacket} for this entity with all of its attributes values. + * Gets an {@link EntityAttributesPacket} for this entity with all of its attributes values. * - * @return an {@link EntityPropertiesPacket} linked to this entity + * @return an {@link EntityAttributesPacket} linked to this entity */ - protected @NotNull EntityPropertiesPacket getPropertiesPacket() { - return new EntityPropertiesPacket(getEntityId(), List.copyOf(attributeModifiers.values())); + protected @NotNull EntityAttributesPacket getPropertiesPacket() { + return new EntityAttributesPacket(getEntityId(), List.copyOf(attributeModifiers.values())); } /** @@ -667,7 +667,7 @@ public class LivingEntity extends Entity implements EquipmentHandler { */ @Override public void takeKnockback(float strength, final double x, final double z) { - strength *= 1 - getAttributeValue(Attribute.KNOCKBACK_RESISTANCE); + strength *= (float) (1 - getAttributeValue(Attribute.GENERIC_KNOCKBACK_RESISTANCE)); super.takeKnockback(strength, x, z); } } diff --git a/src/main/java/net/minestom/server/entity/Metadata.java b/src/main/java/net/minestom/server/entity/Metadata.java index f208bf2db..791e8bfaf 100644 --- a/src/main/java/net/minestom/server/entity/Metadata.java +++ b/src/main/java/net/minestom/server/entity/Metadata.java @@ -3,6 +3,7 @@ package net.minestom.server.entity; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.text.Component; import net.minestom.server.coordinate.Point; +import net.minestom.server.entity.metadata.animal.ArmadilloMeta; import net.minestom.server.entity.metadata.animal.FrogMeta; import net.minestom.server.entity.metadata.animal.SnifferMeta; import net.minestom.server.entity.metadata.animal.tameable.CatMeta; @@ -19,10 +20,8 @@ import org.jetbrains.annotations.UnknownNullability; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; public final class Metadata { public static Entry Byte(byte value) { @@ -50,11 +49,11 @@ public final class Metadata { } public static Entry OptChat(@Nullable Component value) { - return new MetadataImpl.EntryImpl<>(TYPE_OPTCHAT, value, NetworkBuffer.OPT_CHAT); + return new MetadataImpl.EntryImpl<>(TYPE_OPT_CHAT, value, NetworkBuffer.OPT_CHAT); } - public static Entry Slot(@NotNull ItemStack value) { - return new MetadataImpl.EntryImpl<>(TYPE_SLOT, value, NetworkBuffer.ITEM); + public static Entry ItemStack(@NotNull ItemStack value) { + return new MetadataImpl.EntryImpl<>(TYPE_ITEM_STACK, value, NetworkBuffer.ITEM); } public static Entry Boolean(boolean value) { @@ -65,12 +64,12 @@ public final class Metadata { return new MetadataImpl.EntryImpl<>(TYPE_ROTATION, value, NetworkBuffer.VECTOR3); } - public static Entry Position(@NotNull Point value) { - return new MetadataImpl.EntryImpl<>(TYPE_POSITION, value, NetworkBuffer.BLOCK_POSITION); + public static Entry BlockPosition(@NotNull Point value) { + return new MetadataImpl.EntryImpl<>(TYPE_BLOCK_POSITION, value, NetworkBuffer.BLOCK_POSITION); } - public static Entry OptPosition(@Nullable Point value) { - return new MetadataImpl.EntryImpl<>(TYPE_OPTPOSITION, value, NetworkBuffer.OPT_BLOCK_POSITION); + public static Entry OptBlockPosition(@Nullable Point value) { + return new MetadataImpl.EntryImpl<>(TYPE_OPT_BLOCK_POSITION, value, NetworkBuffer.OPT_BLOCK_POSITION); } public static Entry Direction(@NotNull Direction value) { @@ -78,7 +77,7 @@ public final class Metadata { } public static Entry OptUUID(@Nullable UUID value) { - return new MetadataImpl.EntryImpl<>(TYPE_OPTUUID, value, NetworkBuffer.OPT_UUID); + return new MetadataImpl.EntryImpl<>(TYPE_OPT_UUID, value, NetworkBuffer.OPT_UUID); } public static Entry BlockState(@Nullable Integer value) { @@ -86,22 +85,38 @@ public final class Metadata { } public static Entry OptBlockState(@Nullable Integer value) { - return new MetadataImpl.EntryImpl<>(TYPE_OPTBLOCKSTATE, value, NetworkBuffer.OPT_BLOCK_STATE); + return new MetadataImpl.EntryImpl<>(TYPE_OPT_BLOCKSTATE, value, NetworkBuffer.OPT_BLOCK_STATE); } public static Entry NBT(@NotNull BinaryTag nbt) { return new MetadataImpl.EntryImpl<>(TYPE_NBT, nbt, NetworkBuffer.NBT); } - public static Entry VillagerData(int villagerType, - int villagerProfession, - int level) { + public static Entry Particle(@NotNull Particle particle) { + return new MetadataImpl.EntryImpl<>(TYPE_PARTICLE, particle, NetworkBuffer.PARTICLE); + } + + public static Entry> ParticleList(@NotNull List particles) { + return new MetadataImpl.EntryImpl<>(TYPE_PARTICLE_LIST, particles, new NetworkBuffer.Type<>() { + @Override + public void write(@NotNull NetworkBuffer buffer, List value) { + buffer.writeCollection(NetworkBuffer.PARTICLE, value); + } + + @Override + public List read(@NotNull NetworkBuffer buffer) { + return buffer.readCollection(NetworkBuffer.PARTICLE, Integer.MAX_VALUE); + } + }); + } + + public static Entry VillagerData(int villagerType, int villagerProfession, int level) { return new MetadataImpl.EntryImpl<>(TYPE_VILLAGERDATA, new int[]{villagerType, villagerProfession, level}, NetworkBuffer.VILLAGER_DATA); } public static Entry OptVarInt(@Nullable Integer value) { - return new MetadataImpl.EntryImpl<>(TYPE_OPTVARINT, value, new NetworkBuffer.Type<>() { + return new MetadataImpl.EntryImpl<>(TYPE_OPT_VARINT, value, new NetworkBuffer.Type<>() { @Override public void write(@NotNull NetworkBuffer buffer, Integer value) { buffer.write(NetworkBuffer.VAR_INT, value == null ? 0 : value + 1); @@ -123,18 +138,24 @@ public final class Metadata { return new MetadataImpl.EntryImpl<>(TYPE_CAT_VARIANT, value, NetworkBuffer.CAT_VARIANT); } + // WOLF VARIANT + public static Entry FrogVariant(@NotNull FrogMeta.Variant value) { return new MetadataImpl.EntryImpl<>(TYPE_FROG_VARIANT, value, NetworkBuffer.FROG_VARIANT); } public static Entry PaintingVariant(@NotNull PaintingMeta.Variant value) { - return new MetadataImpl.EntryImpl<>(TYPE_PAINTINGVARIANT, value, NetworkBuffer.PAINTING_VARIANT); + return new MetadataImpl.EntryImpl<>(TYPE_PAINTING_VARIANT, value, NetworkBuffer.PAINTING_VARIANT); } public static Entry SnifferState(@NotNull SnifferMeta.State value) { return new MetadataImpl.EntryImpl<>(TYPE_SNIFFER_STATE, value, NetworkBuffer.SNIFFER_STATE); } + public static Entry ArmadilloState(@NotNull ArmadilloMeta.State value) { + return new MetadataImpl.EntryImpl<>(TYPE_ARMADILLO_STATE, value, NetworkBuffer.ARMADILLO_STATE); + } + public static Entry Vector3(@NotNull Point value) { return new MetadataImpl.EntryImpl<>(TYPE_VECTOR3, value, NetworkBuffer.VECTOR3); } @@ -143,41 +164,46 @@ public final class Metadata { return new MetadataImpl.EntryImpl<>(TYPE_QUATERNION, value, NetworkBuffer.QUATERNION); } - public static Entry Particle(@NotNull Particle particle) { - return new MetadataImpl.EntryImpl<>(TYPE_PARTICLE, particle, NetworkBuffer.PARTICLE); - } + private static final AtomicInteger NEXT_ID = new AtomicInteger(0); - public static final byte TYPE_BYTE = 0; - public static final byte TYPE_VARINT = 1; - public static final byte TYPE_LONG = 2; - public static final byte TYPE_FLOAT = 3; - public static final byte TYPE_STRING = 4; - public static final byte TYPE_CHAT = 5; - public static final byte TYPE_OPTCHAT = 6; - public static final byte TYPE_SLOT = 7; - public static final byte TYPE_BOOLEAN = 8; - public static final byte TYPE_ROTATION = 9; - public static final byte TYPE_POSITION = 10; - public static final byte TYPE_OPTPOSITION = 11; - public static final byte TYPE_DIRECTION = 12; - public static final byte TYPE_OPTUUID = 13; - public static final byte TYPE_BLOCKSTATE = 14; - public static final byte TYPE_OPTBLOCKSTATE = 15; - public static final byte TYPE_NBT = 16; - public static final byte TYPE_PARTICLE = 17; - public static final byte TYPE_VILLAGERDATA = 18; - public static final byte TYPE_OPTVARINT = 19; - public static final byte TYPE_POSE = 20; - public static final byte TYPE_CAT_VARIANT = 21; - public static final byte TYPE_FROG_VARIANT = 22; - public static final byte TYPE_OPTGLOBALPOS = 23; - public static final byte TYPE_PAINTINGVARIANT = 24; - public static final byte TYPE_SNIFFER_STATE = 25; - public static final byte TYPE_VECTOR3 = 26; - public static final byte TYPE_QUATERNION = 27; + public static final byte TYPE_BYTE = nextId(); + public static final byte TYPE_VARINT = nextId(); + public static final byte TYPE_LONG = nextId(); + public static final byte TYPE_FLOAT = nextId(); + public static final byte TYPE_STRING = nextId(); + public static final byte TYPE_CHAT = nextId(); + public static final byte TYPE_OPT_CHAT = nextId(); + public static final byte TYPE_ITEM_STACK = nextId(); + public static final byte TYPE_BOOLEAN = nextId(); + public static final byte TYPE_ROTATION = nextId(); + public static final byte TYPE_BLOCK_POSITION = nextId(); + public static final byte TYPE_OPT_BLOCK_POSITION = nextId(); + public static final byte TYPE_DIRECTION = nextId(); + public static final byte TYPE_OPT_UUID = nextId(); + public static final byte TYPE_BLOCKSTATE = nextId(); + public static final byte TYPE_OPT_BLOCKSTATE = nextId(); + public static final byte TYPE_NBT = nextId(); + public static final byte TYPE_PARTICLE = nextId(); + public static final byte TYPE_PARTICLE_LIST = nextId(); + public static final byte TYPE_VILLAGERDATA = nextId(); + public static final byte TYPE_OPT_VARINT = nextId(); + public static final byte TYPE_POSE = nextId(); + public static final byte TYPE_CAT_VARIANT = nextId(); + public static final byte TYPE_WOLF_VARIANT = nextId(); + public static final byte TYPE_FROG_VARIANT = nextId(); + public static final byte TYPE_OPT_GLOBAL_POSITION = nextId(); // Unused by protocol it seems + public static final byte TYPE_PAINTING_VARIANT = nextId(); + public static final byte TYPE_SNIFFER_STATE = nextId(); + public static final byte TYPE_ARMADILLO_STATE = nextId(); + public static final byte TYPE_VECTOR3 = nextId(); + public static final byte TYPE_QUATERNION = nextId(); // Impl Note: Adding an entry here requires that a default value entry is added in MetadataImpl.EMPTY_VALUES + private static byte nextId() { + return (byte) NEXT_ID.getAndIncrement(); + } + private static final VarHandle NOTIFIED_CHANGES; static { diff --git a/src/main/java/net/minestom/server/entity/MetadataImpl.java b/src/main/java/net/minestom/server/entity/MetadataImpl.java index 8a58a9d4e..ba46d47d3 100644 --- a/src/main/java/net/minestom/server/entity/MetadataImpl.java +++ b/src/main/java/net/minestom/server/entity/MetadataImpl.java @@ -3,6 +3,7 @@ package net.minestom.server.entity; import net.kyori.adventure.nbt.EndBinaryTag; import net.kyori.adventure.text.Component; import net.minestom.server.coordinate.Vec; +import net.minestom.server.entity.metadata.animal.ArmadilloMeta; import net.minestom.server.entity.metadata.animal.FrogMeta; import net.minestom.server.entity.metadata.animal.SnifferMeta; import net.minestom.server.entity.metadata.animal.tameable.CatMeta; @@ -10,11 +11,14 @@ import net.minestom.server.entity.metadata.other.PaintingMeta; import net.minestom.server.instance.block.Block; import net.minestom.server.item.ItemStack; import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.particle.Particle; import net.minestom.server.utils.Direction; import net.minestom.server.utils.collection.ObjectArray; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.UnknownNullability; +import java.util.List; + import static net.minestom.server.entity.Metadata.*; import static net.minestom.server.network.NetworkBuffer.VAR_INT; @@ -28,26 +32,29 @@ final class MetadataImpl { EMPTY_VALUES.set(TYPE_FLOAT, Float(0f)); EMPTY_VALUES.set(TYPE_STRING, String("")); EMPTY_VALUES.set(TYPE_CHAT, Chat(Component.empty())); - EMPTY_VALUES.set(TYPE_OPTCHAT, OptChat(null)); - EMPTY_VALUES.set(TYPE_SLOT, Slot(ItemStack.AIR)); + EMPTY_VALUES.set(TYPE_OPT_CHAT, OptChat(null)); + EMPTY_VALUES.set(TYPE_ITEM_STACK, ItemStack(ItemStack.AIR)); EMPTY_VALUES.set(TYPE_BOOLEAN, Boolean(false)); EMPTY_VALUES.set(TYPE_ROTATION, Rotation(Vec.ZERO)); - EMPTY_VALUES.set(TYPE_POSITION, Position(Vec.ZERO)); - EMPTY_VALUES.set(TYPE_OPTPOSITION, OptPosition(null)); + EMPTY_VALUES.set(TYPE_BLOCK_POSITION, BlockPosition(Vec.ZERO)); + EMPTY_VALUES.set(TYPE_OPT_BLOCK_POSITION, OptBlockPosition(null)); EMPTY_VALUES.set(TYPE_DIRECTION, Direction(Direction.DOWN)); - EMPTY_VALUES.set(TYPE_OPTUUID, OptUUID(null)); + EMPTY_VALUES.set(TYPE_OPT_UUID, OptUUID(null)); EMPTY_VALUES.set(TYPE_BLOCKSTATE, BlockState(Block.AIR.id())); - EMPTY_VALUES.set(TYPE_OPTBLOCKSTATE, OptBlockState(null)); + EMPTY_VALUES.set(TYPE_OPT_BLOCKSTATE, OptBlockState(null)); EMPTY_VALUES.set(TYPE_NBT, NBT(EndBinaryTag.endBinaryTag())); - //EMPTY_VALUES.set(TYPE_PARTICLE -> throw new UnsupportedOperationException(); + EMPTY_VALUES.set(TYPE_PARTICLE, Particle(Particle.DUST)); + EMPTY_VALUES.set(TYPE_PARTICLE_LIST, ParticleList(List.of())); EMPTY_VALUES.set(TYPE_VILLAGERDATA, VillagerData(0, 0, 0)); - EMPTY_VALUES.set(TYPE_OPTVARINT, OptVarInt(null)); + EMPTY_VALUES.set(TYPE_OPT_VARINT, OptVarInt(null)); EMPTY_VALUES.set(TYPE_POSE, Pose(Entity.Pose.STANDING)); EMPTY_VALUES.set(TYPE_CAT_VARIANT, CatVariant(CatMeta.Variant.TABBY)); + // WolfVariant EMPTY_VALUES.set(TYPE_FROG_VARIANT, FrogVariant(FrogMeta.Variant.TEMPERATE)); // OptGlobalPos - EMPTY_VALUES.set(TYPE_PAINTINGVARIANT, PaintingVariant(PaintingMeta.Variant.KEBAB)); + EMPTY_VALUES.set(TYPE_PAINTING_VARIANT, PaintingVariant(PaintingMeta.Variant.KEBAB)); EMPTY_VALUES.set(TYPE_SNIFFER_STATE, SnifferState(SnifferMeta.State.IDLING)); + EMPTY_VALUES.set(TYPE_ARMADILLO_STATE, ArmadilloState(ArmadilloMeta.State.IDLE)); EMPTY_VALUES.set(TYPE_VECTOR3, Vector3(Vec.ZERO)); EMPTY_VALUES.set(TYPE_QUATERNION, Quaternion(new float[]{0, 0, 0, 0})); EMPTY_VALUES.trim(); diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index e45f1e367..d0b5a19ca 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -25,13 +25,13 @@ import net.minestom.server.advancements.AdvancementTab; import net.minestom.server.adventure.AdventurePacketConvertor; import net.minestom.server.adventure.Localizable; import net.minestom.server.adventure.audience.Audiences; -import net.minestom.server.attribute.Attribute; import net.minestom.server.collision.BoundingBox; import net.minestom.server.command.CommandSender; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; import net.minestom.server.effects.Effects; +import net.minestom.server.entity.attribute.Attribute; import net.minestom.server.entity.damage.DamageType; import net.minestom.server.entity.metadata.LivingEntityMeta; import net.minestom.server.entity.metadata.PlayerMeta; @@ -251,7 +251,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, this.gameMode = GameMode.SURVIVAL; this.dimensionType = DimensionType.OVERWORLD; // Default dimension this.levelFlat = true; - getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.1f); + getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.1); // FakePlayer init its connection there playerConnectionInit(); @@ -293,8 +293,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable, final JoinGamePacket joinGamePacket = new JoinGamePacket( getEntityId(), this.hardcore, List.of(), 0, ServerFlag.CHUNK_VIEW_DISTANCE, ServerFlag.CHUNK_VIEW_DISTANCE, - false, true, false, dimensionType.toString(), spawnInstance.getDimensionName(), - 0, gameMode, null, false, levelFlat, deathLocation, portalCooldown); + false, true, false, dimensionType.getId(), spawnInstance.getDimensionName(), + 0, gameMode, null, false, levelFlat, deathLocation, portalCooldown, true); sendPacket(joinGamePacket); // Difficulty @@ -523,7 +523,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, setOnFire(false); refreshHealth(); - sendPacket(new RespawnPacket(getDimensionType().toString(), instance.getDimensionName(), + sendPacket(new RespawnPacket(getDimensionType().getId(), instance.getDimensionName(), 0, gameMode, gameMode, false, levelFlat, deathLocation, portalCooldown, RespawnPacket.COPY_ALL)); refreshClientStateAfterRespawn(); @@ -1202,7 +1202,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, final PlayerInfoRemovePacket removePlayerPacket = getRemovePlayerToList(); final PlayerInfoUpdatePacket addPlayerPacket = getAddPlayerToList(); - RespawnPacket respawnPacket = new RespawnPacket(getDimensionType().toString(), instance.getDimensionName(), + RespawnPacket respawnPacket = new RespawnPacket(getDimensionType().getId(), instance.getDimensionName(), 0, gameMode, gameMode, false, levelFlat, deathLocation, portalCooldown, RespawnPacket.COPY_ALL); sendPacket(removePlayerPacket); @@ -1653,7 +1653,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, Check.argCondition(instance.getDimensionName().equals(dimensionName), "The dimension needs to be different than the current one!"); this.dimensionType = dimensionType; - sendPacket(new RespawnPacket(dimensionType.toString(), dimensionName, + sendPacket(new RespawnPacket(dimensionType.getId(), dimensionName, 0, gameMode, gameMode, false, levelFlat, deathLocation, portalCooldown, RespawnPacket.COPY_ALL)); refreshClientStateAfterRespawn(); diff --git a/src/main/java/net/minestom/server/entity/attribute/Attribute.java b/src/main/java/net/minestom/server/entity/attribute/Attribute.java new file mode 100644 index 000000000..51e5e4d37 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/attribute/Attribute.java @@ -0,0 +1,59 @@ +package net.minestom.server.entity.attribute; + +import net.minestom.server.registry.Registry; +import net.minestom.server.registry.StaticProtocolObject; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public sealed interface Attribute extends StaticProtocolObject, Attributes permits AttributeImpl { + + @Contract(pure = true) + @NotNull Registry.AttributeEntry registry(); + + @Override + default @NotNull NamespaceID namespace() { + return registry().namespace(); + } + + @Override + default int id() { + return registry().id(); + } + + default double defaultValue() { + return registry().defaultValue(); + } + + default double minValue() { + return registry().minValue(); + } + + default double maxValue() { + return registry().maxValue(); + } + + default boolean isSynced() { + return registry().clientSync(); + } + + static @NotNull Collection<@NotNull Attribute> values() { + return AttributeImpl.values(); + } + + static @Nullable Attribute fromNamespaceId(@NotNull String namespaceID) { + return AttributeImpl.getSafe(namespaceID); + } + + static @Nullable Attribute fromNamespaceId(@NotNull NamespaceID namespaceID) { + return fromNamespaceId(namespaceID.asString()); + } + + static @Nullable Attribute fromId(int id) { + return AttributeImpl.getId(id); + } + +} diff --git a/src/main/java/net/minestom/server/entity/attribute/AttributeImpl.java b/src/main/java/net/minestom/server/entity/attribute/AttributeImpl.java new file mode 100644 index 000000000..89ba36f58 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/attribute/AttributeImpl.java @@ -0,0 +1,32 @@ +package net.minestom.server.entity.attribute; + +import net.minestom.server.registry.Registry; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +record AttributeImpl(@NotNull Registry.AttributeEntry registry) implements Attribute { + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ATTRIBUTES, + (namespace, properties) -> new AttributeImpl(Registry.attribute(namespace, properties))); + + static Attribute get(@NotNull String namespace) { + return CONTAINER.get(namespace); + } + + static Attribute getSafe(@NotNull String namespace) { + return CONTAINER.getSafe(namespace); + } + + static Attribute getId(int id) { + return CONTAINER.getId(id); + } + + static Collection values() { + return CONTAINER.values(); + } + + @Override + public String toString() { + return name(); + } +} diff --git a/src/main/java/net/minestom/server/attribute/AttributeInstance.java b/src/main/java/net/minestom/server/entity/attribute/AttributeInstance.java similarity index 91% rename from src/main/java/net/minestom/server/attribute/AttributeInstance.java rename to src/main/java/net/minestom/server/entity/attribute/AttributeInstance.java index e123792f6..c26416941 100644 --- a/src/main/java/net/minestom/server/attribute/AttributeInstance.java +++ b/src/main/java/net/minestom/server/entity/attribute/AttributeInstance.java @@ -1,4 +1,4 @@ -package net.minestom.server.attribute; +package net.minestom.server.entity.attribute; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -16,8 +16,8 @@ public final class AttributeInstance { private final Attribute attribute; private final Map modifiers = new HashMap<>(); private final Consumer propertyChangeListener; - private float baseValue; - private float cachedValue = 0.0f; + private double baseValue; + private double cachedValue = 0.0f; public AttributeInstance(@NotNull Attribute attribute, @Nullable Consumer listener) { this.attribute = attribute; @@ -39,9 +39,9 @@ public final class AttributeInstance { * The base value of this instance without modifiers * * @return the instance base value - * @see #setBaseValue(float) + * @see #setBaseValue(double) */ - public float getBaseValue() { + public double getBaseValue() { return baseValue; } @@ -51,7 +51,7 @@ public final class AttributeInstance { * @param baseValue the new base value * @see #getBaseValue() */ - public void setBaseValue(float baseValue) { + public void setBaseValue(double baseValue) { if (this.baseValue != baseValue) { this.baseValue = baseValue; refreshCachedValue(); @@ -104,7 +104,7 @@ public final class AttributeInstance { * * @return the attribute value */ - public float getValue() { + public double getValue() { return cachedValue; } @@ -113,13 +113,13 @@ public final class AttributeInstance { */ private void refreshCachedValue() { final Collection modifiers = getModifiers(); - float base = getBaseValue(); + double base = getBaseValue(); for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.ADDITION).toArray(AttributeModifier[]::new)) { base += modifier.getAmount(); } - float result = base; + double result = base; for (var modifier : modifiers.stream().filter(mod -> mod.getOperation() == AttributeOperation.MULTIPLY_BASE).toArray(AttributeModifier[]::new)) { result += (base * modifier.getAmount()); diff --git a/src/main/java/net/minestom/server/attribute/AttributeModifier.java b/src/main/java/net/minestom/server/entity/attribute/AttributeModifier.java similarity index 97% rename from src/main/java/net/minestom/server/attribute/AttributeModifier.java rename to src/main/java/net/minestom/server/entity/attribute/AttributeModifier.java index 143b5ef58..9e3f90c18 100644 --- a/src/main/java/net/minestom/server/attribute/AttributeModifier.java +++ b/src/main/java/net/minestom/server/entity/attribute/AttributeModifier.java @@ -1,4 +1,4 @@ -package net.minestom.server.attribute; +package net.minestom.server.entity.attribute; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/minestom/server/attribute/AttributeOperation.java b/src/main/java/net/minestom/server/entity/attribute/AttributeOperation.java similarity index 92% rename from src/main/java/net/minestom/server/attribute/AttributeOperation.java rename to src/main/java/net/minestom/server/entity/attribute/AttributeOperation.java index 33da291c7..acf09ab91 100644 --- a/src/main/java/net/minestom/server/attribute/AttributeOperation.java +++ b/src/main/java/net/minestom/server/entity/attribute/AttributeOperation.java @@ -1,4 +1,4 @@ -package net.minestom.server.attribute; +package net.minestom.server.entity.attribute; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/net/minestom/server/entity/damage/DamageType.java b/src/main/java/net/minestom/server/entity/damage/DamageType.java index 2d2a20cc2..11aaa611a 100644 --- a/src/main/java/net/minestom/server/entity/damage/DamageType.java +++ b/src/main/java/net/minestom/server/entity/damage/DamageType.java @@ -1,6 +1,6 @@ package net.minestom.server.entity.damage; -import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minestom.server.network.packet.server.configuration.RegistryDataPacket; import net.minestom.server.registry.Registry; import net.minestom.server.registry.StaticProtocolObject; import net.minestom.server.utils.NamespaceID; @@ -36,7 +36,7 @@ public sealed interface DamageType extends StaticProtocolObject, DamageTypes per return registry().scaling(); } - CompoundBinaryTag asNBT(); + @NotNull RegistryDataPacket.Entry toRegistryEntry(); static @NotNull Collection<@NotNull DamageType> values() { return DamageTypeImpl.values(); @@ -54,7 +54,7 @@ public sealed interface DamageType extends StaticProtocolObject, DamageTypes per return DamageTypeImpl.getId(id); } - static CompoundBinaryTag getNBT() { - return DamageTypeImpl.getNBT(); + static @NotNull RegistryDataPacket registryDataPacket() { + return DamageTypeImpl.registryDataPacket(); } } \ No newline at end of file diff --git a/src/main/java/net/minestom/server/entity/damage/DamageTypeImpl.java b/src/main/java/net/minestom/server/entity/damage/DamageTypeImpl.java index b8480e656..4e8777338 100644 --- a/src/main/java/net/minestom/server/entity/damage/DamageTypeImpl.java +++ b/src/main/java/net/minestom/server/entity/damage/DamageTypeImpl.java @@ -1,8 +1,7 @@ package net.minestom.server.entity.damage; -import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.kyori.adventure.nbt.ListBinaryTag; +import net.minestom.server.network.packet.server.configuration.RegistryDataPacket; import net.minestom.server.registry.Registry; import org.jetbrains.annotations.NotNull; @@ -30,13 +29,14 @@ record DamageTypeImpl(Registry.DamageTypeEntry registry, int id) implements Dama return CONTAINER.getId(id); } + @Override - public CompoundBinaryTag asNBT() { - return CompoundBinaryTag.builder() + public @NotNull RegistryDataPacket.Entry toRegistryEntry() { + return new RegistryDataPacket.Entry(name(), CompoundBinaryTag.builder() .putFloat("exhaustion", registry.exhaustion()) .putString("message_id", registry.messageId()) .putString("scaling", registry.scaling()) - .build(); + .build()); } static Collection values() { @@ -53,24 +53,15 @@ record DamageTypeImpl(Registry.DamageTypeEntry registry, int id) implements Dama return id; } - private static CompoundBinaryTag lazyNbt = null; + private static RegistryDataPacket lazyRegistryDataPacket = null; - static CompoundBinaryTag getNBT() { - if (lazyNbt == null) { - var entries = ListBinaryTag.builder(BinaryTagTypes.COMPOUND); - for (var damageType : values()) { - entries.add(CompoundBinaryTag.builder() - .putInt("id", damageType.id()) - .putString("name", damageType.name()) - .put("element", damageType.asNBT()) - .build()); - } - - lazyNbt = CompoundBinaryTag.builder() - .putString("type", "minecraft:damage_type") - .put("value", entries.build()) - .build(); - } - return lazyNbt; + static @NotNull RegistryDataPacket registryDataPacket() { + if (lazyRegistryDataPacket != null) return lazyRegistryDataPacket; + return lazyRegistryDataPacket = new RegistryDataPacket( + "minecraft:damage_type", + values().stream() + .map(DamageType::toRegistryEntry) + .toList() + ); } } \ No newline at end of file diff --git a/src/main/java/net/minestom/server/entity/metadata/LivingEntityMeta.java b/src/main/java/net/minestom/server/entity/metadata/LivingEntityMeta.java index 60d7102b2..ee841f83a 100644 --- a/src/main/java/net/minestom/server/entity/metadata/LivingEntityMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/LivingEntityMeta.java @@ -4,9 +4,12 @@ import net.minestom.server.coordinate.Point; import net.minestom.server.entity.Entity; import net.minestom.server.entity.Metadata; import net.minestom.server.entity.Player; +import net.minestom.server.particle.Particle; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + public class LivingEntityMeta extends EntityMeta { public static final byte OFFSET = EntityMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 7; @@ -44,58 +47,28 @@ public class LivingEntityMeta extends EntityMeta { setMaskBit(OFFSET, IS_IN_SPIN_ATTACK_BIT, value); } - public float getHealth() { - return super.metadata.getIndex(OFFSET + 1, 1F); + public @NotNull List getEffectParticles() { + return super.metadata.getIndex(OFFSET + 1, List.of()); } - public void setHealth(float value) { - super.metadata.setIndex(OFFSET + 1, Metadata.Float(value)); - } - - public int getPotionEffectColor() { - return super.metadata.getIndex(OFFSET + 2, 0); - } - - public void setPotionEffectColor(int value) { - super.metadata.setIndex(OFFSET + 2, Metadata.VarInt(value)); + public void setEffectParticles(@NotNull List value) { + super.metadata.setIndex(OFFSET + 1, Metadata.ParticleList(value)); } public boolean isPotionEffectAmbient() { - return super.metadata.getIndex(OFFSET + 3, false); + return super.metadata.getIndex(OFFSET + 2, false); } public void setPotionEffectAmbient(boolean value) { - super.metadata.setIndex(OFFSET + 3, Metadata.Boolean(value)); + super.metadata.setIndex(OFFSET + 2, Metadata.Boolean(value)); } public int getArrowCount() { - return super.metadata.getIndex(OFFSET + 4, 0); + return super.metadata.getIndex(OFFSET + 3, 0); } public void setArrowCount(int value) { - super.metadata.setIndex(OFFSET + 4, Metadata.VarInt(value)); - } - - /** - * @deprecated - * This returns the bee stinger count, not the absorption heart count - * Use {@link #getBeeStingerCount()} instead - * @return The number of bee stingers in this entity - */ - @Deprecated - public int getHealthAddedByAbsorption() { - return super.metadata.getIndex(OFFSET + 5, 0); - } - - /** - * @deprecated - * This sets the bee stinger count, not the absorption heart count - * Use {@link #setBeeStingerCount(int)} instead - * @param value The number of bee stingers for this entity to have - */ - @Deprecated - public void setHealthAddedByAbsorption(int value) { - super.metadata.setIndex(OFFSET + 5, Metadata.VarInt(value)); + super.metadata.setIndex(OFFSET + 3, Metadata.VarInt(value)); } /** @@ -103,7 +76,7 @@ public class LivingEntityMeta extends EntityMeta { * @return The amount of bee stingers */ public int getBeeStingerCount() { - return super.metadata.getIndex(OFFSET + 5, 0); + return super.metadata.getIndex(OFFSET + 4, 0); } /** @@ -111,7 +84,15 @@ public class LivingEntityMeta extends EntityMeta { * @param value The amount of bee stingers to set, use 0 to clear all stingers */ public void setBeeStingerCount(int value) { - super.metadata.setIndex(OFFSET + 5, Metadata.VarInt(value)); + super.metadata.setIndex(OFFSET + 4, Metadata.VarInt(value)); + } + + public float getHealth() { + return super.metadata.getIndex(OFFSET + 5, 1F); + } + + public void setHealth(float value) { + super.metadata.setIndex(OFFSET + 5, Metadata.Float(value)); } @Nullable @@ -120,7 +101,7 @@ public class LivingEntityMeta extends EntityMeta { } public void setBedInWhichSleepingPosition(@Nullable Point value) { - super.metadata.setIndex(OFFSET + 6, Metadata.OptPosition(value)); + super.metadata.setIndex(OFFSET + 6, Metadata.OptBlockPosition(value)); } } diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/ArmadilloMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/ArmadilloMeta.java new file mode 100644 index 000000000..a0807cfb8 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/metadata/animal/ArmadilloMeta.java @@ -0,0 +1,32 @@ +package net.minestom.server.entity.metadata.animal; + +import net.minestom.server.entity.Entity; +import net.minestom.server.entity.Metadata; +import org.jetbrains.annotations.NotNull; + +public class ArmadilloMeta extends AnimalMeta { + public static final byte OFFSET = AnimalMeta.MAX_OFFSET; + public static final byte MAX_OFFSET = OFFSET + 1; + + public ArmadilloMeta(@NotNull Entity entity, @NotNull Metadata metadata) { + super(entity, metadata); + } + + @NotNull + public State getState() { + return super.metadata.getIndex(OFFSET, State.IDLE); + } + + public void setState(@NotNull State value) { + super.metadata.setIndex(OFFSET, Metadata.ArmadilloState(value)); + } + + public enum State { + IDLE, + ROLLING, + SCARED, + UNROLLING; + + private static final State[] VALUES = values(); + } +} diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/TurtleMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/TurtleMeta.java index 2f12487ae..cd96cc4f2 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/TurtleMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/TurtleMeta.java @@ -19,7 +19,7 @@ public class TurtleMeta extends AnimalMeta { } public void setBlockPosition(@NotNull Point value) { - super.metadata.setIndex(OFFSET, Metadata.Position(value)); + super.metadata.setIndex(OFFSET, Metadata.BlockPosition(value)); } public boolean isHasEgg() { @@ -43,7 +43,7 @@ public class TurtleMeta extends AnimalMeta { } public void setTravelPosition(@NotNull Point value) { - super.metadata.setIndex(OFFSET + 3, Metadata.Position(value)); + super.metadata.setIndex(OFFSET + 3, Metadata.BlockPosition(value)); } public boolean isGoingHome() { diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/tameable/WolfMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/tameable/WolfMeta.java index ce593bd84..4851ed0cf 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/tameable/WolfMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/tameable/WolfMeta.java @@ -12,6 +12,8 @@ public class WolfMeta extends TameableAnimalMeta { super(entity, metadata); } + //todo variant + public boolean isBegging() { return super.metadata.getIndex(OFFSET, false); } diff --git a/src/main/java/net/minestom/server/entity/metadata/display/ItemDisplayMeta.java b/src/main/java/net/minestom/server/entity/metadata/display/ItemDisplayMeta.java index 5a78687ca..ff5e266fe 100644 --- a/src/main/java/net/minestom/server/entity/metadata/display/ItemDisplayMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/display/ItemDisplayMeta.java @@ -18,7 +18,7 @@ public class ItemDisplayMeta extends AbstractDisplayMeta { } public void setItemStack(@NotNull ItemStack value) { - super.metadata.setIndex(OFFSET, Metadata.Slot(value)); + super.metadata.setIndex(OFFSET, Metadata.ItemStack(value)); } public @NotNull DisplayContext getDisplayContext() { diff --git a/src/main/java/net/minestom/server/entity/metadata/item/ItemContainingMeta.java b/src/main/java/net/minestom/server/entity/metadata/item/ItemContainingMeta.java index 2949ec133..8d403468f 100644 --- a/src/main/java/net/minestom/server/entity/metadata/item/ItemContainingMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/item/ItemContainingMeta.java @@ -24,7 +24,7 @@ class ItemContainingMeta extends EntityMeta { } public void setItem(@NotNull ItemStack item) { - super.metadata.setIndex(OFFSET, Metadata.Slot(item)); + super.metadata.setIndex(OFFSET, Metadata.ItemStack(item)); } } diff --git a/src/main/java/net/minestom/server/entity/metadata/monster/skeleton/BoggedMeta.java b/src/main/java/net/minestom/server/entity/metadata/monster/skeleton/BoggedMeta.java new file mode 100644 index 000000000..da5d5791c --- /dev/null +++ b/src/main/java/net/minestom/server/entity/metadata/monster/skeleton/BoggedMeta.java @@ -0,0 +1,14 @@ +package net.minestom.server.entity.metadata.monster.skeleton; + +import net.minestom.server.entity.Entity; +import net.minestom.server.entity.Metadata; +import org.jetbrains.annotations.NotNull; + +public class BoggedMeta extends AbstractSkeletonMeta { + public static final byte OFFSET = AbstractSkeletonMeta.MAX_OFFSET; + public static final byte MAX_OFFSET = OFFSET + 0; + + public BoggedMeta(@NotNull Entity entity, @NotNull Metadata metadata) { + super(entity, metadata); + } +} diff --git a/src/main/java/net/minestom/server/entity/metadata/other/EndCrystalMeta.java b/src/main/java/net/minestom/server/entity/metadata/other/EndCrystalMeta.java index c4889ddaa..7f1e9fce0 100644 --- a/src/main/java/net/minestom/server/entity/metadata/other/EndCrystalMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/other/EndCrystalMeta.java @@ -20,7 +20,7 @@ public class EndCrystalMeta extends EntityMeta { } public void setBeamTarget(@Nullable Point value) { - super.metadata.setIndex(OFFSET, Metadata.OptPosition(value)); + super.metadata.setIndex(OFFSET, Metadata.OptBlockPosition(value)); } public boolean isShowingBottom() { diff --git a/src/main/java/net/minestom/server/entity/metadata/other/FallingBlockMeta.java b/src/main/java/net/minestom/server/entity/metadata/other/FallingBlockMeta.java index f05fb9327..3bb0ce150 100644 --- a/src/main/java/net/minestom/server/entity/metadata/other/FallingBlockMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/other/FallingBlockMeta.java @@ -24,7 +24,7 @@ public class FallingBlockMeta extends EntityMeta implements ObjectDataProvider { } public void setSpawnPosition(Point value) { - super.metadata.setIndex(OFFSET, Metadata.Position(value)); + super.metadata.setIndex(OFFSET, Metadata.BlockPosition(value)); } @NotNull diff --git a/src/main/java/net/minestom/server/entity/metadata/other/ItemFrameMeta.java b/src/main/java/net/minestom/server/entity/metadata/other/ItemFrameMeta.java index 9fe83fd1e..742e2ffa6 100644 --- a/src/main/java/net/minestom/server/entity/metadata/other/ItemFrameMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/other/ItemFrameMeta.java @@ -25,7 +25,7 @@ public class ItemFrameMeta extends EntityMeta implements ObjectDataProvider { } public void setItem(@NotNull ItemStack value) { - super.metadata.setIndex(OFFSET, Metadata.Slot(value)); + super.metadata.setIndex(OFFSET, Metadata.ItemStack(value)); } @NotNull diff --git a/src/main/java/net/minestom/server/entity/metadata/other/OminousItemSpawnerMeta.java b/src/main/java/net/minestom/server/entity/metadata/other/OminousItemSpawnerMeta.java new file mode 100644 index 000000000..318a88fd2 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/metadata/other/OminousItemSpawnerMeta.java @@ -0,0 +1,25 @@ +package net.minestom.server.entity.metadata.other; + +import net.minestom.server.entity.Entity; +import net.minestom.server.entity.Metadata; +import net.minestom.server.entity.metadata.EntityMeta; +import net.minestom.server.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class OminousItemSpawnerMeta extends EntityMeta { + public static final byte OFFSET = EntityMeta.MAX_OFFSET; + public static final byte MAX_OFFSET = OFFSET + 1; + + public OminousItemSpawnerMeta(@NotNull Entity entity, @NotNull Metadata metadata) { + super(entity, metadata); + } + + public @NotNull ItemStack getItem() { + return super.metadata.getIndex(OFFSET, ItemStack.AIR); + } + + public void setItem(@NotNull ItemStack value) { + super.metadata.setIndex(OFFSET, Metadata.ItemStack(value)); + } + +} diff --git a/src/main/java/net/minestom/server/entity/metadata/projectile/FireworkRocketMeta.java b/src/main/java/net/minestom/server/entity/metadata/projectile/FireworkRocketMeta.java index 65c055236..6c3450d1b 100644 --- a/src/main/java/net/minestom/server/entity/metadata/projectile/FireworkRocketMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/projectile/FireworkRocketMeta.java @@ -3,7 +3,6 @@ package net.minestom.server.entity.metadata.projectile; import net.minestom.server.entity.Entity; import net.minestom.server.entity.Metadata; import net.minestom.server.entity.metadata.EntityMeta; -import net.minestom.server.entity.metadata.projectile.ProjectileMeta; import net.minestom.server.item.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,7 +23,7 @@ public class FireworkRocketMeta extends EntityMeta implements ProjectileMeta { } public void setFireworkInfo(@NotNull ItemStack value) { - super.metadata.setIndex(OFFSET, Metadata.Slot(value)); + super.metadata.setIndex(OFFSET, Metadata.ItemStack(value)); } @Override diff --git a/src/main/java/net/minestom/server/entity/metadata/water/DolphinMeta.java b/src/main/java/net/minestom/server/entity/metadata/water/DolphinMeta.java index 6dca1c672..b4753d46d 100644 --- a/src/main/java/net/minestom/server/entity/metadata/water/DolphinMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/water/DolphinMeta.java @@ -20,7 +20,7 @@ public class DolphinMeta extends WaterAnimalMeta { } public void setTreasurePosition(@NotNull Point value) { - super.metadata.setIndex(OFFSET, Metadata.Position(value)); + super.metadata.setIndex(OFFSET, Metadata.BlockPosition(value)); } public boolean isHasFish() { diff --git a/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java b/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java index a8e6a7422..ac7780e87 100644 --- a/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java +++ b/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java @@ -4,11 +4,11 @@ import com.extollit.gaming.ai.path.model.Gravitation; import com.extollit.gaming.ai.path.model.IPathingEntity; import com.extollit.gaming.ai.path.model.Passibility; import com.extollit.linalg.immutable.Vec3d; -import net.minestom.server.attribute.Attribute; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Entity; import net.minestom.server.entity.LivingEntity; +import net.minestom.server.entity.attribute.Attribute; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -34,7 +34,7 @@ public final class PFPathingEntity implements IPathingEntity { this.navigator = navigator; this.entity = navigator.getEntity(); - this.searchRange = getAttributeValue(Attribute.FOLLOW_RANGE); + this.searchRange = (float) getAttributeValue(Attribute.GENERIC_FOLLOW_RANGE); } @Override @@ -138,7 +138,7 @@ public final class PFPathingEntity implements IPathingEntity { return new Capabilities() { @Override public float speed() { - return getAttributeValue(Attribute.MOVEMENT_SPEED); + return (float) getAttributeValue(Attribute.GENERIC_MOVEMENT_SPEED); } @Override @@ -191,7 +191,7 @@ public final class PFPathingEntity implements IPathingEntity { @Override public void moveTo(Vec3d position, Passibility passibility, Gravitation gravitation) { final Point targetPosition = new Vec(position.x, position.y, position.z); - this.navigator.moveTowards(targetPosition, getAttributeValue(Attribute.MOVEMENT_SPEED)); + this.navigator.moveTowards(targetPosition, getAttributeValue(Attribute.GENERIC_MOVEMENT_SPEED)); final double entityY = entity.getPosition().y() + 0.00001D; // After any negative y movement, entities will always be extremely // slightly below floor level. This +0.00001D is here to offset this // error and stop the entity from permanently jumping. @@ -217,7 +217,7 @@ public final class PFPathingEntity implements IPathingEntity { return (float) entity.getBoundingBox().height(); } - private float getAttributeValue(@NotNull Attribute attribute) { + private double getAttributeValue(@NotNull Attribute attribute) { if (entity instanceof LivingEntity) { return ((LivingEntity) entity).getAttributeValue(attribute); } diff --git a/src/main/java/net/minestom/server/item/ItemSerializers.java b/src/main/java/net/minestom/server/item/ItemSerializers.java index c2b6494bc..6764589c6 100644 --- a/src/main/java/net/minestom/server/item/ItemSerializers.java +++ b/src/main/java/net/minestom/server/item/ItemSerializers.java @@ -1,7 +1,7 @@ package net.minestom.server.item; -import net.minestom.server.attribute.Attribute; -import net.minestom.server.attribute.AttributeOperation; +import net.minestom.server.entity.attribute.Attribute; +import net.minestom.server.entity.attribute.AttributeOperation; import net.minestom.server.item.attribute.AttributeSlot; import net.minestom.server.item.attribute.ItemAttribute; import net.minestom.server.tag.Tag; @@ -57,7 +57,7 @@ public final class ItemSerializers { final int operation = reader.getTag(OPERATION); final String name = reader.getTag(NAME); - final Attribute attribute = Attribute.fromKey(attributeName.toLowerCase(Locale.ROOT)); + final Attribute attribute = Attribute.fromNamespaceId(attributeName.toLowerCase(Locale.ROOT)); // Wrong attribute name, stop here if (attribute == null) return null; final AttributeOperation attributeOperation = AttributeOperation.fromId(operation); @@ -79,7 +79,7 @@ public final class ItemSerializers { writer.setTag(ID, value.uuid()); writer.setTag(AMOUNT, value.amount()); writer.setTag(SLOT, value.slot().name().toLowerCase(Locale.ROOT)); - writer.setTag(ATTRIBUTE_NAME, value.attribute().key()); + writer.setTag(ATTRIBUTE_NAME, value.attribute().name()); writer.setTag(OPERATION, value.operation().getId()); writer.setTag(NAME, value.name()); } diff --git a/src/main/java/net/minestom/server/item/Material.java b/src/main/java/net/minestom/server/item/Material.java index efb8eab74..011633e34 100644 --- a/src/main/java/net/minestom/server/item/Material.java +++ b/src/main/java/net/minestom/server/item/Material.java @@ -1,8 +1,8 @@ package net.minestom.server.item; import net.minestom.server.instance.block.Block; -import net.minestom.server.registry.StaticProtocolObject; import net.minestom.server.registry.Registry; +import net.minestom.server.registry.StaticProtocolObject; import net.minestom.server.utils.NamespaceID; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -10,6 +10,38 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; +/** + * + * Component notes + * todo delete me + * + * ItemComponent.DYED_ITEM -> record DyedItemComponent.class + * + * itemStack.with(ItemComponent.DYED_ITEM, new DyedItemComponent(Color.RED)) + * itemStack.get(ItemComponent.DYED_ITEM) + * itemStack.getOrDefault(ItemComponent.DYED_ITEM, new DyedItemComponent(Color.RED)) + * + * material.prototype() -> some component list? + * + * + * + * // NEW WIRE FORMAT + * count | varint + * material id | varint + * components | SEE BELOW + * + * DataComponentPatch + * additions | varint + * removals | varint + * for each addition + * varint | data component id + * data component | data component (depends) + * for each removal + * varint | data component id + * + * + */ + public sealed interface Material extends StaticProtocolObject, Materials permits MaterialImpl { /** diff --git a/src/main/java/net/minestom/server/item/attribute/ItemAttribute.java b/src/main/java/net/minestom/server/item/attribute/ItemAttribute.java index 1e14f1999..e914d4eff 100644 --- a/src/main/java/net/minestom/server/item/attribute/ItemAttribute.java +++ b/src/main/java/net/minestom/server/item/attribute/ItemAttribute.java @@ -1,7 +1,7 @@ package net.minestom.server.item.attribute; -import net.minestom.server.attribute.Attribute; -import net.minestom.server.attribute.AttributeOperation; +import net.minestom.server.entity.attribute.Attribute; +import net.minestom.server.entity.attribute.AttributeOperation; import org.jetbrains.annotations.NotNull; import java.util.UUID; diff --git a/src/main/java/net/minestom/server/item/component/CustomData.java b/src/main/java/net/minestom/server/item/component/CustomData.java new file mode 100644 index 000000000..0c00926ea --- /dev/null +++ b/src/main/java/net/minestom/server/item/component/CustomData.java @@ -0,0 +1,23 @@ +package net.minestom.server.item.component; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.tag.Tag; +import org.jetbrains.annotations.NotNull; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +public record CustomData(@NotNull NBTCompound nbt) implements ItemComponent { + static final Tag TAG = Tag.Structure("ab", CustomData.class); + + static final NetworkBuffer.Type NETWORK_TYPE = new NetworkBuffer.Type<>() { + @Override + public void write(@NotNull NetworkBuffer buffer, CustomData value) { + buffer.write(NetworkBuffer.NBT, value.nbt); + } + + @Override + public CustomData read(@NotNull NetworkBuffer buffer) { + return new CustomData((NBTCompound) buffer.read(NetworkBuffer.NBT)); + } + }; + +} diff --git a/src/main/java/net/minestom/server/item/component/ItemComponent.java b/src/main/java/net/minestom/server/item/component/ItemComponent.java new file mode 100644 index 000000000..2cc339d29 --- /dev/null +++ b/src/main/java/net/minestom/server/item/component/ItemComponent.java @@ -0,0 +1,20 @@ +package net.minestom.server.item.component; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.tag.Tag; +import org.jetbrains.annotations.NotNull; + +public sealed interface ItemComponent permits CustomData { + + ItemComponent.Type CUSTOM_DATA = new ItemComponent.Type<>("custom_data", CustomData.NETWORK_TYPE, CustomData.TAG); + + record Type( + @NotNull String name, + @NotNull NetworkBuffer.Type network, + @NotNull Tag tag + ) { + + } + + +} diff --git a/src/main/java/net/minestom/server/item/metadata/PotionMeta.java b/src/main/java/net/minestom/server/item/metadata/PotionMeta.java index a4ecfcc2e..00742b003 100644 --- a/src/main/java/net/minestom/server/item/metadata/PotionMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/PotionMeta.java @@ -13,7 +13,7 @@ import org.jetbrains.annotations.UnknownNullability; import java.util.List; public record PotionMeta(TagReadable readable) implements ItemMetaView { - private static final Tag POTION_TYPE = Tag.String("Potion").map(PotionType::fromNamespaceId, StaticProtocolObject::name).defaultValue(PotionType.EMPTY); + private static final Tag POTION_TYPE = Tag.String("Potion").map(PotionType::fromNamespaceId, StaticProtocolObject::name).defaultValue(PotionType.WATER); private static final Tag> CUSTOM_POTION_EFFECTS = Tag.Structure("CustomPotionEffects", new TagSerializer() { @Override public @Nullable CustomPotionEffect read(@NotNull TagReadable reader) { diff --git a/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java b/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java index 13ea23024..06ec2f836 100644 --- a/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java +++ b/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java @@ -40,8 +40,8 @@ public final class HandshakeListener { public static void listener(@NotNull ClientHandshakePacket packet, @NotNull PlayerConnection connection) { String address = packet.serverAddress(); switch (packet.intent()) { - case 1 -> connection.setConnectionState(ConnectionState.STATUS); - case 2 -> { + case STATUS -> connection.setConnectionState(ConnectionState.STATUS); + case LOGIN -> { connection.setConnectionState(ConnectionState.LOGIN); if (packet.protocolVersion() != MinecraftServer.PROTOCOL_VERSION) { // Incorrect client version @@ -114,6 +114,9 @@ public final class HandshakeListener { } } } + case TRANSFER -> { + throw new UnsupportedOperationException("Transfer intent is not supported in HandshakeListener"); + } default -> { // Unexpected error } diff --git a/src/main/java/net/minestom/server/listener/preplay/LoginListener.java b/src/main/java/net/minestom/server/listener/preplay/LoginListener.java index 15df756e7..55b3308e7 100644 --- a/src/main/java/net/minestom/server/listener/preplay/LoginListener.java +++ b/src/main/java/net/minestom/server/listener/preplay/LoginListener.java @@ -75,7 +75,7 @@ public final class LoginListener { byte[] nonce = new byte[4]; ThreadLocalRandom.current().nextBytes(nonce); socketConnection.setNonce(nonce); - socketConnection.sendPacket(new EncryptionRequestPacket("", publicKey, nonce)); + socketConnection.sendPacket(new EncryptionRequestPacket("", publicKey, nonce, true)); } else { final boolean bungee = BungeeCordProxy.isEnabled(); // Offline diff --git a/src/main/java/net/minestom/server/message/Messenger.java b/src/main/java/net/minestom/server/message/Messenger.java index df3d09acb..fdd6abc18 100644 --- a/src/main/java/net/minestom/server/message/Messenger.java +++ b/src/main/java/net/minestom/server/message/Messenger.java @@ -5,6 +5,7 @@ import net.kyori.adventure.nbt.TagStringIO; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.entity.Player; +import net.minestom.server.network.packet.server.configuration.RegistryDataPacket; import net.minestom.server.network.packet.server.play.SystemChatPacket; import net.minestom.server.utils.PacketUtils; import org.jetbrains.annotations.NotNull; @@ -12,6 +13,7 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.Collection; +import java.util.List; import java.util.Objects; import java.util.UUID; @@ -26,44 +28,36 @@ public final class Messenger { private static final UUID NO_SENDER = new UUID(0, 0); private static final SystemChatPacket CANNOT_SEND_PACKET = new SystemChatPacket(CANNOT_SEND_MESSAGE, false); - private static final CompoundBinaryTag CHAT_REGISTRY; + private static final RegistryDataPacket REGISTRY_DATA_PACKET; static { try { - CHAT_REGISTRY = TagStringIO.get().asCompound( - """ - { - "type": "minecraft:chat_type", - "value": [ - { - "name":"minecraft:chat", - "id":1, - "element":{ - "chat":{ - "translation_key":"chat.type.text", - "parameters":[ - "sender", - "content" - ] - }, - "narration":{ - "translation_key":"chat.type.text.narrate", - "parameters":[ - "sender", - "content" - ] - } - } - } ] - }""" - ); + REGISTRY_DATA_PACKET = new RegistryDataPacket( + "minecraft:chat_type", List.of( + new RegistryDataPacket.Entry( + "minecraft:chat", + TagStringIO.get().asCompound( + """ + { + "chat":{ + "translation_key":"chat.type.text", + "parameters":["sender", "content"] + }, + "narration":{ + "translation_key":"chat.type.text.narrate", + "parameters":["sender", "content"] + } + }""" + ) + ) + )); } catch (IOException e) { throw new RuntimeException(e); } } - public static @NotNull CompoundBinaryTag chatRegistry() { - return CHAT_REGISTRY; + public static @NotNull RegistryDataPacket registryDataPacket() { + return REGISTRY_DATA_PACKET; } /** diff --git a/src/main/java/net/minestom/server/network/ConnectionManager.java b/src/main/java/net/minestom/server/network/ConnectionManager.java index ec78114e9..fb3238dd1 100644 --- a/src/main/java/net/minestom/server/network/ConnectionManager.java +++ b/src/main/java/net/minestom/server/network/ConnectionManager.java @@ -1,6 +1,5 @@ package net.minestom.server.network; -import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.MinecraftServer; @@ -18,7 +17,6 @@ import net.minestom.server.network.packet.server.common.KeepAlivePacket; import net.minestom.server.network.packet.server.common.PluginMessagePacket; import net.minestom.server.network.packet.server.common.TagsPacket; import net.minestom.server.network.packet.server.configuration.FinishConfigurationPacket; -import net.minestom.server.network.packet.server.configuration.RegistryDataPacket; import net.minestom.server.network.packet.server.login.LoginSuccessPacket; import net.minestom.server.network.packet.server.play.StartConfigurationPacket; import net.minestom.server.network.player.PlayerConnection; @@ -33,8 +31,6 @@ import org.jctools.queues.MpscUnboundedArrayQueue; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -282,15 +278,15 @@ public final class ConnectionManager { // Registry data (if it should be sent) if (event.willSendRegistryData()) { - var registryCompound = CompoundBinaryTag.builder() - .put("minecraft:chat_type", Messenger.chatRegistry()) - .put("minecraft:dimension_type", MinecraftServer.getDimensionTypeManager().toNBT()) - .put("minecraft:worldgen/biome", MinecraftServer.getBiomeManager().toNBT()) - .put("minecraft:damage_type", DamageType.getNBT()) -// .put("minecraft:trim_material", MinecraftServer.getTrimManager().getTrimMaterialNBT()) -// .put("minecraft:trim_pattern", MinecraftServer.getTrimManager().getTrimPatternNBT()) - .build(); - player.sendPacket(new RegistryDataPacket(registryCompound)); + + // minecraft:trim_pattern, minecraft:trim_material, minecraft:wolf_variant, and minecraft:banner_pattern. + + player.sendPacket(Messenger.registryDataPacket()); + player.sendPacket(MinecraftServer.getDimensionTypeManager().registryDataPacket()); + player.sendPacket(MinecraftServer.getBiomeManager().registryDataPacket()); + player.sendPacket(DamageType.registryDataPacket()); +// registry.put("minecraft:trim_material", MinecraftServer.getTrimManager().getTrimMaterialNBT()); +// registry.put("minecraft:trim_pattern", MinecraftServer.getTrimManager().getTrimPatternNBT()); player.sendPacket(TagsPacket.DEFAULT_TAGS); } diff --git a/src/main/java/net/minestom/server/network/NetworkBuffer.java b/src/main/java/net/minestom/server/network/NetworkBuffer.java index 7f1b9a267..8f074f60c 100644 --- a/src/main/java/net/minestom/server/network/NetworkBuffer.java +++ b/src/main/java/net/minestom/server/network/NetworkBuffer.java @@ -4,6 +4,7 @@ import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.text.Component; import net.minestom.server.coordinate.Point; import net.minestom.server.entity.Entity; +import net.minestom.server.entity.metadata.animal.ArmadilloMeta; import net.minestom.server.entity.metadata.animal.FrogMeta; import net.minestom.server.entity.metadata.animal.SnifferMeta; import net.minestom.server.entity.metadata.animal.tameable.CatMeta; @@ -73,6 +74,7 @@ public final class NetworkBuffer { public static final Type FROG_VARIANT = NetworkBufferTypeImpl.fromEnum(FrogMeta.Variant.class); public static final Type PAINTING_VARIANT = NetworkBufferTypeImpl.fromEnum(PaintingMeta.Variant.class); public static final Type SNIFFER_STATE = NetworkBufferTypeImpl.fromEnum(SnifferMeta.State.class); + public static final Type ARMADILLO_STATE = NetworkBufferTypeImpl.fromEnum(ArmadilloMeta.State.class); ByteBuffer nioBuffer; @@ -301,6 +303,11 @@ public final class NetworkBuffer { void write(@NotNull NetworkBuffer writer); } + @FunctionalInterface + public interface Reader { + @NotNull T read(@NotNull NetworkBuffer reader); + } + public static byte[] makeArray(@NotNull Consumer<@NotNull NetworkBuffer> writing) { NetworkBuffer writer = new NetworkBuffer(); writing.accept(writer); diff --git a/src/main/java/net/minestom/server/network/NetworkBufferTypeImpl.java b/src/main/java/net/minestom/server/network/NetworkBufferTypeImpl.java index 3a2e2e4d0..6347280d2 100644 --- a/src/main/java/net/minestom/server/network/NetworkBufferTypeImpl.java +++ b/src/main/java/net/minestom/server/network/NetworkBufferTypeImpl.java @@ -399,32 +399,28 @@ interface NetworkBufferTypeImpl extends NetworkBuffer.Type { @Override public void write(@NotNull NetworkBuffer buffer, ItemStack value) { if (value.isAir()) { - buffer.write(BOOLEAN, false); + buffer.write(VAR_INT, 0); // 0 count always return; } - buffer.write(BOOLEAN, true); + buffer.write(VAR_INT, value.amount()); buffer.write(VAR_INT, value.material().id()); - buffer.write(BYTE, (byte) value.amount()); - // Vanilla does not write an empty object, just an end tag. - CompoundBinaryTag nbt = value.meta().toNBT(); - buffer.write(NBT, nbt.size() == 0 ? EndBinaryTag.endBinaryTag() : nbt); + buffer.write(VAR_INT, 0); // Added components + buffer.write(VAR_INT, 0); // Removed components } @Override public ItemStack read(@NotNull NetworkBuffer buffer) { - final boolean present = buffer.read(BOOLEAN); - if (!present) return ItemStack.AIR; + int count = buffer.read(VAR_INT); + if (count <= 0) return ItemStack.AIR; final int id = buffer.read(VAR_INT); final Material material = Material.fromId(id); if (material == null) throw new RuntimeException("Unknown material id: " + id); - final int amount = buffer.read(BYTE); - final BinaryTag nbt = buffer.read(NBT); - if (!(nbt instanceof CompoundBinaryTag compound)) { - return ItemStack.of(material, amount); - } - return ItemStack.fromNBT(material, compound, amount); + buffer.read(VAR_INT); // Added components + buffer.read(VAR_INT); // Removed components + + return ItemStack.fromNBT(material, new NBTCompound(), count); } } diff --git a/src/main/java/net/minestom/server/network/packet/client/ClientPacketsHandler.java b/src/main/java/net/minestom/server/network/packet/client/ClientPacketsHandler.java index 80ec4e5c1..91d739fa4 100644 --- a/src/main/java/net/minestom/server/network/packet/client/ClientPacketsHandler.java +++ b/src/main/java/net/minestom/server/network/packet/client/ClientPacketsHandler.java @@ -3,6 +3,7 @@ package net.minestom.server.network.packet.client; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.packet.client.common.*; import net.minestom.server.network.packet.client.configuration.ClientFinishConfigurationPacket; +import net.minestom.server.network.packet.client.configuration.ClientSelectKnownPacksPacket; import net.minestom.server.network.packet.client.login.ClientEncryptionResponsePacket; import net.minestom.server.network.packet.client.login.ClientLoginAcknowledgedPacket; import net.minestom.server.network.packet.client.login.ClientLoginPluginResponsePacket; @@ -13,28 +14,26 @@ import net.minestom.server.utils.collection.ObjectArray; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.UnknownNullability; -import java.util.function.Function; - /** * Contains registered packets and a way to instantiate them. *

- * Packets are registered using {@link #register(int, Function)} and created using {@link #create(int, NetworkBuffer)}. + * Packets are registered using {@link #register(int, NetworkBuffer.Reader)} and created using {@link #create(int, NetworkBuffer)}. */ public sealed class ClientPacketsHandler permits ClientPacketsHandler.Status, ClientPacketsHandler.Login, ClientPacketsHandler.Configuration, ClientPacketsHandler.Play { - private final ObjectArray> suppliers = ObjectArray.singleThread(0x10); + private final ObjectArray> suppliers = ObjectArray.singleThread(0x10); private ClientPacketsHandler() { } - public void register(int id, @NotNull Function<@NotNull NetworkBuffer, @NotNull ClientPacket> packetSupplier) { + public void register(int id, @NotNull NetworkBuffer.Reader packetSupplier) { this.suppliers.set(id, packetSupplier); } public @UnknownNullability ClientPacket create(int packetId, @NotNull NetworkBuffer reader) { - final Function supplier = suppliers.get(packetId); + final NetworkBuffer.Reader supplier = suppliers.get(packetId); if (supplier == null) throw new IllegalStateException("Packet id 0x" + Integer.toHexString(packetId) + " isn't registered!"); - return supplier.apply(reader); + return supplier.read(reader); } public static final class Status extends ClientPacketsHandler { @@ -60,6 +59,7 @@ public sealed class ClientPacketsHandler permits ClientPacketsHandler.Status, Cl register(nextId(), ClientEncryptionResponsePacket::new); register(nextId(), ClientLoginPluginResponsePacket::new); register(nextId(), ClientLoginAcknowledgedPacket::new); + register(nextId(), ClientCookieResponsePacket::new); } } @@ -71,11 +71,13 @@ public sealed class ClientPacketsHandler permits ClientPacketsHandler.Status, Cl public Configuration() { register(nextId(), ClientSettingsPacket::new); + register(nextId(), ClientCookieResponsePacket::new); register(nextId(), ClientPluginMessagePacket::new); register(nextId(), ClientFinishConfigurationPacket::new); register(nextId(), ClientKeepAlivePacket::new); register(nextId(), ClientPongPacket::new); register(nextId(), ClientResourcePackStatusPacket::new); + register(nextId(), ClientSelectKnownPacksPacket::new); } } @@ -93,6 +95,7 @@ public sealed class ClientPacketsHandler permits ClientPacketsHandler.Status, Cl nextId(); // difficulty packet register(nextId(), ClientChatAckPacket::new); register(nextId(), ClientCommandChatPacket::new); + register(nextId(), ClientSignedCommandChatPacket::new); register(nextId(), ClientChatMessagePacket::new); register(nextId(), ClientChatSessionUpdatePacket::new); register(nextId(), ClientChunkBatchReceivedPacket::new); @@ -104,7 +107,9 @@ public sealed class ClientPacketsHandler permits ClientPacketsHandler.Status, Cl register(nextId(), ClientClickWindowPacket::new); register(nextId(), ClientCloseWindowPacket::new); register(nextId(), ClientWindowSlotStatePacket::new); + register(nextId(), ClientCookieResponsePacket::new); register(nextId(), ClientPluginMessagePacket::new); + register(nextId(), ClientDebugSampleSubscriptionPacket::new); register(nextId(), ClientEditBookPacket::new); register(nextId(), ClientQueryEntityNbtPacket::new); register(nextId(), ClientInteractEntityPacket::new); diff --git a/src/main/java/net/minestom/server/network/packet/client/common/ClientCookieResponsePacket.java b/src/main/java/net/minestom/server/network/packet/client/common/ClientCookieResponsePacket.java new file mode 100644 index 000000000..25854b758 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/client/common/ClientCookieResponsePacket.java @@ -0,0 +1,35 @@ +package net.minestom.server.network.packet.client.common; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.network.packet.server.common.CookieStorePacket; +import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public record ClientCookieResponsePacket( + @NotNull String key, + byte @Nullable [] value +) implements ClientPacket { + + public ClientCookieResponsePacket { + Check.argCondition(value != null && value.length > CookieStorePacket.MAX_VALUE_LENGTH, + "Value is too long: {0} > {1}", value != null ? value.length : 0, CookieStorePacket.MAX_VALUE_LENGTH); + } + + public ClientCookieResponsePacket(@NotNull NetworkBuffer reader) { + this(reader.read(NetworkBuffer.STRING), reader.readOptional(buffer -> { + int valueLength = buffer.read(NetworkBuffer.VAR_INT); + Check.argCondition(valueLength > CookieStorePacket.MAX_VALUE_LENGTH, + "Value is too long: {0} > {1}", valueLength, CookieStorePacket.MAX_VALUE_LENGTH); + return buffer.readBytes(valueLength); + })); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(NetworkBuffer.STRING, key); + writer.writeOptional(NetworkBuffer.BYTE_ARRAY, value); + } + +} diff --git a/src/main/java/net/minestom/server/network/packet/client/configuration/ClientSelectKnownPacksPacket.java b/src/main/java/net/minestom/server/network/packet/client/configuration/ClientSelectKnownPacksPacket.java new file mode 100644 index 000000000..2e263ea84 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/client/configuration/ClientSelectKnownPacksPacket.java @@ -0,0 +1,29 @@ +package net.minestom.server.network.packet.client.configuration; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.network.packet.server.configuration.SelectKnownPacksPacket; +import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public record ClientSelectKnownPacksPacket( + @NotNull List entries +) implements ClientPacket { + private static final int MAX_ENTRIES = 64; + + public ClientSelectKnownPacksPacket { + Check.argCondition(entries.size() > MAX_ENTRIES, "Too many known packs: {0} > {1}", entries.size(), MAX_ENTRIES); + } + + public ClientSelectKnownPacksPacket(@NotNull NetworkBuffer reader) { + this(reader.readCollection(SelectKnownPacksPacket.Entry::new, MAX_ENTRIES)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.writeCollection(entries); + } + +} diff --git a/src/main/java/net/minestom/server/network/packet/client/handshake/ClientHandshakePacket.java b/src/main/java/net/minestom/server/network/packet/client/handshake/ClientHandshakePacket.java index bd1432190..1517a4d62 100644 --- a/src/main/java/net/minestom/server/network/packet/client/handshake/ClientHandshakePacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/handshake/ClientHandshakePacket.java @@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull; import static net.minestom.server.network.NetworkBuffer.*; public record ClientHandshakePacket(int protocolVersion, @NotNull String serverAddress, - int serverPort, int intent) implements ClientPacket { + int serverPort, @NotNull Intent intent) implements ClientPacket { public ClientHandshakePacket { if (serverAddress.length() > getMaxHandshakeLength()) { @@ -18,7 +18,7 @@ public record ClientHandshakePacket(int protocolVersion, @NotNull String serverA public ClientHandshakePacket(@NotNull NetworkBuffer reader) { this(reader.read(VAR_INT), reader.read(STRING), - reader.read(UNSIGNED_SHORT), reader.read(VAR_INT)); + reader.read(UNSIGNED_SHORT), Intent.fromId(reader.read(VAR_INT))); } @Override @@ -30,7 +30,7 @@ public record ClientHandshakePacket(int protocolVersion, @NotNull String serverA } writer.write(STRING, serverAddress); writer.write(UNSIGNED_SHORT, serverPort); - writer.write(VAR_INT, intent); + writer.write(VAR_INT, intent.id()); } private static int getMaxHandshakeLength() { @@ -38,4 +38,23 @@ public record ClientHandshakePacket(int protocolVersion, @NotNull String serverA return BungeeCordProxy.isEnabled() ? (BungeeCordProxy.isBungeeGuardEnabled() ? 2500 : Short.MAX_VALUE) : 255; } + public enum Intent { + STATUS, + LOGIN, + TRANSFER; + + public static @NotNull Intent fromId(int id) { + return switch (id) { + case 1 -> STATUS; + case 2 -> LOGIN; + case 3 -> TRANSFER; + default -> throw new IllegalArgumentException("Unknown connection intent: " + id); + }; + } + + public int id() { + return ordinal() + 1; + } + } + } diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientCommandChatPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientCommandChatPacket.java index ef29ff546..66b302b3e 100644 --- a/src/main/java/net/minestom/server/network/packet/client/play/ClientCommandChatPacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientCommandChatPacket.java @@ -1,35 +1,23 @@ package net.minestom.server.network.packet.client.play; -import net.minestom.server.crypto.ArgumentSignatures; -import net.minestom.server.crypto.LastSeenMessages; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; -import static net.minestom.server.network.NetworkBuffer.LONG; import static net.minestom.server.network.NetworkBuffer.STRING; -public record ClientCommandChatPacket(@NotNull String message, long timestamp, - long salt, @NotNull ArgumentSignatures signatures, - LastSeenMessages.@NotNull Update lastSeenMessages) implements ClientPacket { +public record ClientCommandChatPacket(@NotNull String message) implements ClientPacket { public ClientCommandChatPacket { - if (message.length() > 256) { - throw new IllegalArgumentException("Message length cannot be greater than 256"); - } + Check.argCondition(message.length() > 256, "Message length cannot be greater than 256"); } public ClientCommandChatPacket(@NotNull NetworkBuffer reader) { - this(reader.read(STRING), reader.read(LONG), - reader.read(LONG), new ArgumentSignatures(reader), - new LastSeenMessages.Update(reader)); + this(reader.read(STRING)); } @Override public void write(@NotNull NetworkBuffer writer) { writer.write(STRING, message); - writer.write(LONG, timestamp); - writer.write(LONG, salt); - writer.write(signatures); - writer.write(lastSeenMessages); } } diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientDebugSampleSubscriptionPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientDebugSampleSubscriptionPacket.java new file mode 100644 index 000000000..2fd208907 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientDebugSampleSubscriptionPacket.java @@ -0,0 +1,18 @@ +package net.minestom.server.network.packet.client.play; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.network.packet.server.play.DebugSamplePacket; +import org.jetbrains.annotations.NotNull; + +public record ClientDebugSampleSubscriptionPacket(@NotNull DebugSamplePacket.Type type) implements ClientPacket { + + public ClientDebugSampleSubscriptionPacket(@NotNull NetworkBuffer reader) { + this(reader.readEnum(DebugSamplePacket.Type.class)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.writeEnum(DebugSamplePacket.Type.class, type); + } +} diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientSignedCommandChatPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientSignedCommandChatPacket.java new file mode 100644 index 000000000..3693b80e8 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientSignedCommandChatPacket.java @@ -0,0 +1,34 @@ +package net.minestom.server.network.packet.client.play; + +import net.minestom.server.crypto.ArgumentSignatures; +import net.minestom.server.crypto.LastSeenMessages; +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.client.ClientPacket; +import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.NotNull; + +import static net.minestom.server.network.NetworkBuffer.LONG; +import static net.minestom.server.network.NetworkBuffer.STRING; + +public record ClientSignedCommandChatPacket(@NotNull String message, long timestamp, + long salt, @NotNull ArgumentSignatures signatures, + LastSeenMessages.@NotNull Update lastSeenMessages) implements ClientPacket { + public ClientSignedCommandChatPacket { + Check.argCondition(message.length() > 256, "Message length cannot be greater than 256"); + } + + public ClientSignedCommandChatPacket(@NotNull NetworkBuffer reader) { + this(reader.read(STRING), reader.read(LONG), + reader.read(LONG), new ArgumentSignatures(reader), + new LastSeenMessages.Update(reader)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(STRING, message); + writer.write(LONG, timestamp); + writer.write(LONG, salt); + writer.write(signatures); + writer.write(lastSeenMessages); + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java b/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java index c6afcdc87..3390174ff 100644 --- a/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java +++ b/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java @@ -3,27 +3,36 @@ package net.minestom.server.network.packet.server; import java.util.concurrent.atomic.AtomicInteger; public final class ServerPacketIdentifier { + private static final AtomicInteger STATUS_ID = new AtomicInteger(0); + private static final AtomicInteger LOGIN_ID = new AtomicInteger(0); + private static final AtomicInteger CONFIGURATION_ID = new AtomicInteger(0); private static final AtomicInteger PLAY_ID = new AtomicInteger(0); - public static final int STATUS_RESPONSE = 0x00; - public static final int STATUS_PING_RESPONSE = 0x01; + public static final int STATUS_RESPONSE = nextStatusId(); + public static final int STATUS_PING_RESPONSE = nextStatusId(); - public static final int LOGIN_DISCONNECT = 0x00; - public static final int LOGIN_ENCRYPTION_REQUEST = 0x01; - public static final int LOGIN_SUCCESS = 0x02; - public static final int LOGIN_SET_COMPRESSION = 0x03; - public static final int LOGIN_PLUGIN_REQUEST = 0x04; + public static final int LOGIN_DISCONNECT = nextLoginId(); + public static final int LOGIN_ENCRYPTION_REQUEST = nextLoginId(); + public static final int LOGIN_SUCCESS = nextLoginId(); + public static final int LOGIN_SET_COMPRESSION = nextLoginId(); + public static final int LOGIN_PLUGIN_REQUEST = nextLoginId(); + public static final int LOGIN_COOKIE_REQUEST = nextLoginId(); - public static final int CONFIGURATION_PLUGIN_MESSAGE = 0x00; - public static final int CONFIGURATION_DISCONNECT = 0x01; - public static final int CONFIGURATION_FINISH_CONFIGURATION = 0x02; - public static final int CONFIGURATION_KEEP_ALIVE = 0x03; - public static final int CONFIGURATION_PING = 0x04; - public static final int CONFIGURATION_REGISTRY_DATA = 0x05; - public static final int CONFIGURATION_RESOURCE_PACK_POP_PACKET = 0x06; - public static final int CONFIGURATION_RESOURCE_PACK_PUSH_PACKET = 0x07; - public static final int CONFIGURATION_UPDATE_ENABLED_FEATURES = 0x08; - public static final int CONFIGURATION_TAGS = 0x09; + public static final int CONFIGURATION_COOKIE_REQUEST = nextConfigurationId(); + public static final int CONFIGURATION_PLUGIN_MESSAGE = nextConfigurationId(); + public static final int CONFIGURATION_DISCONNECT = nextConfigurationId(); + public static final int CONFIGURATION_FINISH_CONFIGURATION = nextConfigurationId(); + public static final int CONFIGURATION_KEEP_ALIVE = nextConfigurationId(); + public static final int CONFIGURATION_PING = nextConfigurationId(); + public static final int CONFIGURATION_RESET_CHAT = nextConfigurationId(); + public static final int CONFIGURATION_REGISTRY_DATA = nextConfigurationId(); + public static final int CONFIGURATION_RESOURCE_PACK_POP = nextConfigurationId(); + public static final int CONFIGURATION_RESOURCE_PACK_PUSH = nextConfigurationId(); + public static final int CONFIGURATION_COOKIE_STORE = nextConfigurationId(); + public static final int CONFIGURATION_TRANSFER = nextConfigurationId(); + public static final int CONFIGURATION_UPDATE_ENABLED_FEATURES = nextConfigurationId(); + public static final int CONFIGURATION_TAGS = nextConfigurationId(); + public static final int CONFIGURATION_SELECT_KNOWN_PACKS = nextConfigurationId(); public static final int BUNDLE = nextPlayId(); public static final int SPAWN_ENTITY = nextPlayId(); @@ -47,10 +56,12 @@ public final class ServerPacketIdentifier { public static final int WINDOW_ITEMS = nextPlayId(); public static final int WINDOW_PROPERTY = nextPlayId(); public static final int SET_SLOT = nextPlayId(); + public static final int COOKIE_REQUEST = nextPlayId(); public static final int SET_COOLDOWN = nextPlayId(); public static final int CUSTOM_CHAT_COMPLETIONS = nextPlayId(); public static final int PLUGIN_MESSAGE = nextPlayId(); public static final int DAMAGE_EVENT = nextPlayId(); + public static final int DEBUG_SAMPLE = nextPlayId(); public static final int DELETE_CHAT_MESSAGE = nextPlayId(); public static final int DISCONNECT = nextPlayId(); public static final int DISGUISED_CHAT = nextPlayId(); @@ -130,6 +141,7 @@ public final class ServerPacketIdentifier { public static final int SOUND_EFFECT = nextPlayId(); public static final int START_CONFIGURATION_PACKET = nextPlayId(); public static final int STOP_SOUND = nextPlayId(); + public static final int COOKIE_STORE = nextPlayId(); public static final int SYSTEM_CHAT = nextPlayId(); public static final int PLAYER_LIST_HEADER_AND_FOOTER = nextPlayId(); public static final int NBT_QUERY_RESPONSE = nextPlayId(); @@ -137,11 +149,25 @@ public final class ServerPacketIdentifier { public static final int ENTITY_TELEPORT = nextPlayId(); public static final int TICK_STATE = nextPlayId(); public static final int TICK_STEP = nextPlayId(); + public static final int TRANSFER = nextPlayId(); public static final int ADVANCEMENTS = nextPlayId(); - public static final int ENTITY_PROPERTIES = nextPlayId(); + public static final int ENTITY_ATTRIBUTES = nextPlayId(); public static final int ENTITY_EFFECT = nextPlayId(); public static final int DECLARE_RECIPES = nextPlayId(); public static final int TAGS = nextPlayId(); + public static final int PROJECTILE_POWER = nextPlayId(); + + private static int nextStatusId() { + return STATUS_ID.getAndIncrement(); + } + + private static int nextLoginId() { + return LOGIN_ID.getAndIncrement(); + } + + private static int nextConfigurationId() { + return CONFIGURATION_ID.getAndIncrement(); + } private static int nextPlayId() { return PLAY_ID.getAndIncrement(); diff --git a/src/main/java/net/minestom/server/network/packet/server/common/CookieRequestPacket.java b/src/main/java/net/minestom/server/network/packet/server/common/CookieRequestPacket.java new file mode 100644 index 000000000..853c11b39 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/common/CookieRequestPacket.java @@ -0,0 +1,34 @@ +package net.minestom.server.network.packet.server.common; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import org.jetbrains.annotations.NotNull; + +public record CookieRequestPacket(@NotNull String key) implements + ServerPacket.Login, ServerPacket.Configuration, ServerPacket.Play { + + public CookieRequestPacket(@NotNull NetworkBuffer reader) { + this(reader.read(NetworkBuffer.STRING)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(NetworkBuffer.STRING, key); + } + + @Override + public int configurationId() { + return ServerPacketIdentifier.CONFIGURATION_COOKIE_REQUEST; + } + + @Override + public int loginId() { + return ServerPacketIdentifier.LOGIN_COOKIE_REQUEST; + } + + @Override + public int playId() { + return ServerPacketIdentifier.COOKIE_REQUEST; + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/common/CookieStorePacket.java b/src/main/java/net/minestom/server/network/packet/server/common/CookieStorePacket.java new file mode 100644 index 000000000..42775547f --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/common/CookieStorePacket.java @@ -0,0 +1,54 @@ +package net.minestom.server.network.packet.server.common; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.NamespaceID; +import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.NotNull; + +public record CookieStorePacket( + @NotNull String key, byte[] value +) implements ServerPacket.Configuration, ServerPacket.Play { + public static final int MAX_VALUE_LENGTH = 5120; + + public CookieStorePacket { + Check.argCondition(value.length > MAX_VALUE_LENGTH, "Cookie value length too long: {0} > {1}", value.length, MAX_VALUE_LENGTH); + } + + public CookieStorePacket(@NotNull NamespaceID key, byte[] value) { + this(key.asString(), value); + } + + public CookieStorePacket(@NotNull NetworkBuffer reader) { + this(read(reader)); + } + + private CookieStorePacket(@NotNull CookieStorePacket other) { + this(other.key, other.value); + } + + private static @NotNull CookieStorePacket read(@NotNull NetworkBuffer reader) { + String key = reader.read(NetworkBuffer.STRING); + int valueLength = reader.read(NetworkBuffer.VAR_INT); + Check.argCondition(valueLength > MAX_VALUE_LENGTH, "Cookie value length too long: {0} > {1}", valueLength, MAX_VALUE_LENGTH); + byte[] value = reader.readBytes(valueLength); + return new CookieStorePacket(key, value); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(NetworkBuffer.STRING, key); + writer.write(NetworkBuffer.BYTE_ARRAY, value); + } + + @Override + public int configurationId() { + return ServerPacketIdentifier.CONFIGURATION_COOKIE_STORE; + } + + @Override + public int playId() { + return ServerPacketIdentifier.COOKIE_STORE; + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/common/ResourcePackPopPacket.java b/src/main/java/net/minestom/server/network/packet/server/common/ResourcePackPopPacket.java index a6774a3d7..82adfd113 100644 --- a/src/main/java/net/minestom/server/network/packet/server/common/ResourcePackPopPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/common/ResourcePackPopPacket.java @@ -20,7 +20,7 @@ public record ResourcePackPopPacket(@Nullable UUID id) implements ServerPacket.C @Override public int configurationId() { - return ServerPacketIdentifier.CONFIGURATION_RESOURCE_PACK_POP_PACKET; + return ServerPacketIdentifier.CONFIGURATION_RESOURCE_PACK_POP; } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/common/ResourcePackPushPacket.java b/src/main/java/net/minestom/server/network/packet/server/common/ResourcePackPushPacket.java index a2b2f5e80..b585c2152 100644 --- a/src/main/java/net/minestom/server/network/packet/server/common/ResourcePackPushPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/common/ResourcePackPushPacket.java @@ -42,7 +42,7 @@ public record ResourcePackPushPacket( @Override public int configurationId() { - return ServerPacketIdentifier.CONFIGURATION_RESOURCE_PACK_PUSH_PACKET; + return ServerPacketIdentifier.CONFIGURATION_RESOURCE_PACK_PUSH; } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/common/TransferPacket.java b/src/main/java/net/minestom/server/network/packet/server/common/TransferPacket.java new file mode 100644 index 000000000..968e6b725 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/common/TransferPacket.java @@ -0,0 +1,32 @@ +package net.minestom.server.network.packet.server.common; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import org.jetbrains.annotations.NotNull; + +public record TransferPacket( + @NotNull String host, + int port +) implements ServerPacket.Configuration, ServerPacket.Play { + + public TransferPacket(@NotNull NetworkBuffer reader) { + this(reader.read(NetworkBuffer.STRING), reader.read(NetworkBuffer.VAR_INT)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(NetworkBuffer.STRING, host); + writer.write(NetworkBuffer.VAR_INT, port); + } + + @Override + public int configurationId() { + return ServerPacketIdentifier.CONFIGURATION_TRANSFER; + } + + @Override + public int playId() { + return ServerPacketIdentifier.TRANSFER; + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/configuration/RegistryDataPacket.java b/src/main/java/net/minestom/server/network/packet/server/configuration/RegistryDataPacket.java index 1d8aa950a..df09adb35 100644 --- a/src/main/java/net/minestom/server/network/packet/server/configuration/RegistryDataPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/configuration/RegistryDataPacket.java @@ -5,21 +5,47 @@ import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +import java.util.List; import static net.minestom.server.network.NetworkBuffer.NBT; +import static net.minestom.server.network.NetworkBuffer.STRING; + +public record RegistryDataPacket( + @NotNull String registryId, + @NotNull List entries +) implements ServerPacket.Configuration { -public record RegistryDataPacket(@NotNull CompoundBinaryTag data) implements ServerPacket.Configuration { public RegistryDataPacket(@NotNull NetworkBuffer buffer) { - this((CompoundBinaryTag) buffer.read(NBT)); + this(buffer.read(STRING), buffer.readCollection(Entry::new, Integer.MAX_VALUE)); } @Override public void write(@NotNull NetworkBuffer writer) { - writer.write(NBT, data); + writer.write(STRING, registryId); + writer.writeCollection(entries); } @Override public int configurationId() { return ServerPacketIdentifier.CONFIGURATION_REGISTRY_DATA; } + + public record Entry( + @NotNull String id, + @Nullable CompoundBinaryTag data + ) implements NetworkBuffer.Writer { + + public Entry(@NotNull NetworkBuffer reader) { + this(reader.read(STRING), (CompoundBinaryTag) reader.readOptional(NBT)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(STRING, id); + writer.writeOptional(NBT, data); + } + } } diff --git a/src/main/java/net/minestom/server/network/packet/server/configuration/ResetChatPacket.java b/src/main/java/net/minestom/server/network/packet/server/configuration/ResetChatPacket.java new file mode 100644 index 000000000..f460192f0 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/configuration/ResetChatPacket.java @@ -0,0 +1,23 @@ +package net.minestom.server.network.packet.server.configuration; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import org.jetbrains.annotations.NotNull; + +public record ResetChatPacket() implements ServerPacket.Configuration { + + public ResetChatPacket(@NotNull NetworkBuffer reader) { + this(); // No fields + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + // No fields + } + + @Override + public int configurationId() { + return ServerPacketIdentifier.CONFIGURATION_RESET_CHAT; + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/configuration/SelectKnownPacksPacket.java b/src/main/java/net/minestom/server/network/packet/server/configuration/SelectKnownPacksPacket.java new file mode 100644 index 000000000..61eead13e --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/configuration/SelectKnownPacksPacket.java @@ -0,0 +1,52 @@ +package net.minestom.server.network.packet.server.configuration; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public record SelectKnownPacksPacket( + @NotNull List entries +) implements ServerPacket.Configuration { + private static final int MAX_ENTRIES = 64; + + public SelectKnownPacksPacket { + Check.argCondition(entries.size() > MAX_ENTRIES, "Too many known packs: {0} > {1}", entries.size(), MAX_ENTRIES); + } + + public SelectKnownPacksPacket(@NotNull NetworkBuffer reader) { + this(reader.readCollection(Entry::new, MAX_ENTRIES)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.writeCollection(entries); + } + + @Override + public int configurationId() { + return ServerPacketIdentifier.CONFIGURATION_SELECT_KNOWN_PACKS; + } + + public record Entry( + @NotNull String namespace, + @NotNull String id, + @NotNull String version + ) implements NetworkBuffer.Writer { + public Entry(@NotNull NetworkBuffer reader) { + this(reader.read(NetworkBuffer.STRING), + reader.read(NetworkBuffer.STRING), + reader.read(NetworkBuffer.STRING)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(NetworkBuffer.STRING, namespace); + writer.write(NetworkBuffer.STRING, id); + writer.write(NetworkBuffer.STRING, version); + } + } +} diff --git a/src/main/java/net/minestom/server/network/packet/server/login/EncryptionRequestPacket.java b/src/main/java/net/minestom/server/network/packet/server/login/EncryptionRequestPacket.java index 3a52c731f..99d0dd22f 100644 --- a/src/main/java/net/minestom/server/network/packet/server/login/EncryptionRequestPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/login/EncryptionRequestPacket.java @@ -5,16 +5,20 @@ import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import org.jetbrains.annotations.NotNull; -import static net.minestom.server.network.NetworkBuffer.BYTE_ARRAY; -import static net.minestom.server.network.NetworkBuffer.STRING; +import static net.minestom.server.network.NetworkBuffer.*; + +public record EncryptionRequestPacket( + @NotNull String serverId, + byte @NotNull [] publicKey, + byte @NotNull [] verifyToken, + boolean shouldAuthenticate +) implements ServerPacket.Login { -public record EncryptionRequestPacket(@NotNull String serverId, - byte @NotNull [] publicKey, - byte @NotNull [] verifyToken) implements ServerPacket.Login { public EncryptionRequestPacket(@NotNull NetworkBuffer reader) { this(reader.read(STRING), reader.read(BYTE_ARRAY), - reader.read(BYTE_ARRAY)); + reader.read(BYTE_ARRAY), + reader.read(BOOLEAN)); } @Override @@ -22,6 +26,7 @@ public record EncryptionRequestPacket(@NotNull String serverId, writer.write(STRING, serverId); writer.write(BYTE_ARRAY, publicKey); writer.write(BYTE_ARRAY, verifyToken); + writer.write(BOOLEAN, shouldAuthenticate); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/DebugSamplePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/DebugSamplePacket.java new file mode 100644 index 000000000..4d70d0185 --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/DebugSamplePacket.java @@ -0,0 +1,29 @@ +package net.minestom.server.network.packet.server.play; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import org.jetbrains.annotations.NotNull; + +public record DebugSamplePacket(long @NotNull [] sample, @NotNull Type type) implements ServerPacket.Play { + + public DebugSamplePacket(@NotNull NetworkBuffer buffer) { + this(buffer.read(NetworkBuffer.LONG_ARRAY), buffer.readEnum(Type.class)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(NetworkBuffer.LONG_ARRAY, sample); + writer.writeEnum(Type.class, type); + } + + @Override + public int playId() { + return ServerPacketIdentifier.DEBUG_SAMPLE; + } + + public enum Type { + TICK_TIME + } + +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/DeclareRecipesPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/DeclareRecipesPacket.java index d239800df..4306d4f0a 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/DeclareRecipesPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/DeclareRecipesPacket.java @@ -42,8 +42,8 @@ public record DeclareRecipesPacket(@NotNull List recipes) implem @Override public void write(@NotNull NetworkBuffer writer) { writer.writeCollection(recipes, (bWriter, recipe) -> { - bWriter.write(STRING, recipe.type()); bWriter.write(STRING, recipe.recipeId()); + bWriter.write(STRING, recipe.type()); bWriter.write(recipe); }); } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/EntityPropertiesPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/EntityAttributesPacket.java similarity index 70% rename from src/main/java/net/minestom/server/network/packet/server/play/EntityPropertiesPacket.java rename to src/main/java/net/minestom/server/network/packet/server/play/EntityAttributesPacket.java index 32b786eb1..78859e440 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/EntityPropertiesPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/EntityAttributesPacket.java @@ -1,12 +1,13 @@ package net.minestom.server.network.packet.server.play; -import net.minestom.server.attribute.Attribute; -import net.minestom.server.attribute.AttributeInstance; -import net.minestom.server.attribute.AttributeModifier; -import net.minestom.server.attribute.AttributeOperation; +import net.minestom.server.entity.attribute.Attribute; +import net.minestom.server.entity.attribute.AttributeInstance; +import net.minestom.server.entity.attribute.AttributeModifier; +import net.minestom.server.entity.attribute.AttributeOperation; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -14,16 +15,19 @@ import java.util.List; import static net.minestom.server.network.NetworkBuffer.*; -public record EntityPropertiesPacket(int entityId, List properties) implements ServerPacket.Play { +public record EntityAttributesPacket(int entityId, List properties) implements ServerPacket.Play { public static final int MAX_ENTRIES = 1024; - public EntityPropertiesPacket { + public EntityAttributesPacket { properties = List.copyOf(properties); } - public EntityPropertiesPacket(@NotNull NetworkBuffer reader) { + public EntityAttributesPacket(@NotNull NetworkBuffer reader) { this(reader.read(VAR_INT), reader.readCollection(r -> { - final Attribute attribute = Attribute.fromKey(reader.read(STRING)); + int id = reader.read(VAR_INT); + final Attribute attribute = Attribute.fromId(id); + Check.notNull(attribute, "Unknown attribute id: " + id); + final double value = reader.read(DOUBLE); int modifierCount = reader.read(VAR_INT); AttributeInstance instance = new AttributeInstance(attribute, null); @@ -42,8 +46,8 @@ public record EntityPropertiesPacket(int entityId, List prope for (AttributeInstance instance : properties) { final Attribute attribute = instance.getAttribute(); - writer.write(STRING, attribute.key()); - writer.write(DOUBLE, (double) instance.getBaseValue()); + writer.write(VAR_INT, attribute.id()); + writer.write(DOUBLE, instance.getBaseValue()); { Collection modifiers = instance.getModifiers(); @@ -60,6 +64,6 @@ public record EntityPropertiesPacket(int entityId, List prope @Override public int playId() { - return ServerPacketIdentifier.ENTITY_PROPERTIES; + return ServerPacketIdentifier.ENTITY_ATTRIBUTES; } } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/EntityEffectPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/EntityEffectPacket.java index 35e97f6f1..3024a943e 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/EntityEffectPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/EntityEffectPacket.java @@ -1,27 +1,22 @@ package net.minestom.server.network.packet.server.play; -import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.potion.Potion; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import static net.minestom.server.network.NetworkBuffer.*; +import static net.minestom.server.network.NetworkBuffer.VAR_INT; -public record EntityEffectPacket(int entityId, @NotNull Potion potion, - @Nullable CompoundBinaryTag factorCodec) implements ServerPacket.Play { +public record EntityEffectPacket(int entityId, @NotNull Potion potion) implements ServerPacket.Play { public EntityEffectPacket(@NotNull NetworkBuffer reader) { - this(reader.read(VAR_INT), new Potion(reader), - reader.read(BOOLEAN) ? (CompoundBinaryTag) reader.read(NBT) : null); + this(reader.read(VAR_INT), new Potion(reader)); } @Override public void write(@NotNull NetworkBuffer writer) { writer.write(VAR_INT, entityId); writer.write(potion); - writer.writeOptional(NBT, factorCodec); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/EntityMetaDataPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/EntityMetaDataPacket.java index 900785f41..7bbeb39ac 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/EntityMetaDataPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/EntityMetaDataPacket.java @@ -3,7 +3,6 @@ package net.minestom.server.network.packet.server.play; import net.kyori.adventure.text.Component; import net.minestom.server.entity.Metadata; import net.minestom.server.network.NetworkBuffer; -import net.minestom.server.network.packet.server.ServerPacket.ComponentHolding; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import org.jetbrains.annotations.NotNull; @@ -13,7 +12,8 @@ import java.util.HashMap; import java.util.Map; import java.util.function.UnaryOperator; -import static net.minestom.server.network.NetworkBuffer.*; +import static net.minestom.server.network.NetworkBuffer.BYTE; +import static net.minestom.server.network.NetworkBuffer.VAR_INT; public record EntityMetaDataPacket(int entityId, @NotNull Map> entries) implements ServerPacket.Play, ServerPacket.ComponentHolding { @@ -73,7 +73,7 @@ public record EntityMetaDataPacket(int entityId, if (v instanceof Component c) { var translated = operator.apply(c); - entries.put(key, t == Metadata.TYPE_OPTCHAT ? Metadata.OptChat(translated) : Metadata.Chat(translated)); + entries.put(key, t == Metadata.TYPE_OPT_CHAT ? Metadata.OptChat(translated) : Metadata.Chat(translated)); } else { entries.put(key, value); } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/JoinGamePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/JoinGamePacket.java index 36528e190..69644648e 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/JoinGamePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/JoinGamePacket.java @@ -15,9 +15,10 @@ import static net.minestom.server.network.NetworkBuffer.*; public record JoinGamePacket( int entityId, boolean isHardcore, List worlds, int maxPlayers, int viewDistance, int simulationDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, - boolean doLimitedCrafting, - String dimensionType, String world, long hashedSeed, GameMode gameMode, GameMode previousGameMode, - boolean isDebug, boolean isFlat, WorldPos deathLocation, int portalCooldown + boolean doLimitedCrafting, int dimensionType, + String world, long hashedSeed, GameMode gameMode, GameMode previousGameMode, + boolean isDebug, boolean isFlat, @Nullable WorldPos deathLocation, int portalCooldown, + boolean enforcesSecureChat ) implements ServerPacket.Play { public static final int MAX_WORLDS = Short.MAX_VALUE; @@ -36,8 +37,7 @@ public record JoinGamePacket( reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(BOOLEAN), - - reader.read(STRING), + reader.read(VAR_INT), reader.read(STRING), reader.read(LONG), GameMode.fromId(reader.read(BYTE)), @@ -45,7 +45,8 @@ public record JoinGamePacket( reader.read(BOOLEAN), reader.read(BOOLEAN), reader.read(DEATH_LOCATION), - reader.read(VAR_INT) + reader.read(VAR_INT), + reader.read(BOOLEAN) ); } @@ -60,8 +61,7 @@ public record JoinGamePacket( writer.write(BOOLEAN, reducedDebugInfo); writer.write(BOOLEAN, enableRespawnScreen); writer.write(BOOLEAN, doLimitedCrafting); - - writer.write(STRING, dimensionType); + writer.write(VAR_INT, dimensionType); writer.write(STRING, world); writer.write(LONG, hashedSeed); writer.write(BYTE, gameMode.id()); @@ -74,6 +74,7 @@ public record JoinGamePacket( writer.write(BOOLEAN, isFlat); writer.write(DEATH_LOCATION, deathLocation); writer.write(VAR_INT, portalCooldown); + writer.write(BOOLEAN, enforcesSecureChat); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ProjectilePowerPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ProjectilePowerPacket.java new file mode 100644 index 000000000..e147b15fa --- /dev/null +++ b/src/main/java/net/minestom/server/network/packet/server/play/ProjectilePowerPacket.java @@ -0,0 +1,28 @@ +package net.minestom.server.network.packet.server.play; + +import net.minestom.server.coordinate.Point; +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import org.jetbrains.annotations.NotNull; + +public record ProjectilePowerPacket( + int entityId, @NotNull Point power +) implements ServerPacket.Play { + + public ProjectilePowerPacket(@NotNull NetworkBuffer buffer) { + this(buffer.read(NetworkBuffer.VAR_INT), buffer.read(NetworkBuffer.VECTOR3D)); + } + + @Override + public void write(@NotNull NetworkBuffer writer) { + writer.write(NetworkBuffer.VAR_INT, entityId); + writer.write(NetworkBuffer.VECTOR3D, power); + } + + @Override + public int playId() { + return ServerPacketIdentifier.PROJECTILE_POWER; + } + +} diff --git a/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java index 12eb01e4e..4fa239837 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull; import static net.minestom.server.network.NetworkBuffer.*; public record RespawnPacket( - String dimensionType, String worldName, + int dimensionType, String worldName, long hashedSeed, GameMode gameMode, GameMode previousGameMode, boolean isDebug, boolean isFlat, WorldPos deathLocation, int portalCooldown, int copyData @@ -21,7 +21,7 @@ public record RespawnPacket( public static final int COPY_ALL = COPY_ATTRIBUTES | COPY_METADATA; public RespawnPacket(@NotNull NetworkBuffer reader) { - this(reader.read(STRING), reader.read(STRING), + this(reader.read(VAR_INT), reader.read(STRING), reader.read(LONG), GameMode.fromId(reader.read(BYTE)), GameMode.fromId(reader.read(BYTE)), reader.read(BOOLEAN), reader.read(BOOLEAN), @@ -31,7 +31,7 @@ public record RespawnPacket( @Override public void write(@NotNull NetworkBuffer writer) { - writer.write(STRING, dimensionType); + writer.write(VAR_INT, dimensionType); writer.write(STRING, worldName); writer.write(LONG, hashedSeed); writer.write(BYTE, gameMode.id()); diff --git a/src/main/java/net/minestom/server/potion/Potion.java b/src/main/java/net/minestom/server/potion/Potion.java index 6ad326aa0..4f367f1e9 100644 --- a/src/main/java/net/minestom/server/potion/Potion.java +++ b/src/main/java/net/minestom/server/potion/Potion.java @@ -48,6 +48,11 @@ public record Potion(@NotNull PotionEffect effect, byte amplifier, */ public static final byte ICON_FLAG = 0x04; + /** + * A flag instructing the client to use its builtin blending effect, only used with the darkness effect currently. + */ + public static final byte BLEND_FLAG = 0x08; + /** * A duration constant which sets a Potion duration to infinite. */ @@ -106,6 +111,10 @@ public record Potion(@NotNull PotionEffect effect, byte amplifier, return (flags & ICON_FLAG) == ICON_FLAG; } + public boolean hasBlend() { + return (flags & BLEND_FLAG) == BLEND_FLAG; + } + /** * Sends a packet that a potion effect has been applied to the entity. *

@@ -114,7 +123,7 @@ public record Potion(@NotNull PotionEffect effect, byte amplifier, * @param entity the entity to add the effect to */ public void sendAddPacket(@NotNull Entity entity) { - entity.sendPacketToViewersAndSelf(new EntityEffectPacket(entity.getEntityId(), this, null)); + entity.sendPacketToViewersAndSelf(new EntityEffectPacket(entity.getEntityId(), this)); } /** diff --git a/src/main/java/net/minestom/server/recipe/RecipeManager.java b/src/main/java/net/minestom/server/recipe/RecipeManager.java index 3dac248fb..80587c262 100644 --- a/src/main/java/net/minestom/server/recipe/RecipeManager.java +++ b/src/main/java/net/minestom/server/recipe/RecipeManager.java @@ -57,7 +57,7 @@ public class RecipeManager { case SMITHING_TRIM -> RecipeConversion.smithingTrim((SmithingTrimRecipe) recipe); }); } - return new DeclareRecipesPacket(entries); + return new DeclareRecipesPacket(List.of()); } } diff --git a/src/main/java/net/minestom/server/registry/Registry.java b/src/main/java/net/minestom/server/registry/Registry.java index 93c247089..14868a24a 100644 --- a/src/main/java/net/minestom/server/registry/Registry.java +++ b/src/main/java/net/minestom/server/registry/Registry.java @@ -78,6 +78,11 @@ public final class Registry { return new TrimPatternEntry(namespace, main, null); } + @ApiStatus.Internal + public static AttributeEntry attribute(String namespace, @NotNull Properties main) { + return new AttributeEntry(namespace, main, null); + } + @ApiStatus.Internal public static Map> load(Resource resource) { Map> map = new HashMap<>(); @@ -223,7 +228,8 @@ public final class Registry { FLUID_TAGS("tags/fluid_tags.json"), GAMEPLAY_TAGS("tags/gameplay_tags.json"), ITEM_TAGS("tags/item_tags.json"), - BIOMES("biomes.json"); + BIOMES("biomes.json"), + ATTRIBUTES("attributes.json"); private final String name; @@ -679,6 +685,23 @@ public final class Registry { } } + public record AttributeEntry(NamespaceID namespace, int id, + String translationKey, double defaultValue, + boolean clientSync, + double maxValue, double minValue, + Properties custom) implements Entry { + public AttributeEntry(String namespace, Properties main, Properties custom) { + this(NamespaceID.from(namespace), + main.getInt("id"), + main.getString("translationKey"), + main.getDouble("defaultValue"), + main.getBoolean("clientSync"), + main.getDouble("maxValue"), + main.getDouble("minValue"), + custom); + } + } + public interface Entry { @ApiStatus.Experimental Properties custom(); diff --git a/src/main/java/net/minestom/server/world/DimensionType.java b/src/main/java/net/minestom/server/world/DimensionType.java index c48aed029..7a37771b5 100644 --- a/src/main/java/net/minestom/server/world/DimensionType.java +++ b/src/main/java/net/minestom/server/world/DimensionType.java @@ -1,6 +1,7 @@ package net.minestom.server.world; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minestom.server.network.packet.server.configuration.RegistryDataPacket; import net.minestom.server.utils.NamespaceID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -109,13 +110,8 @@ public class DimensionType { .build(); } - @NotNull - public CompoundBinaryTag toIndexedNBT() { - return CompoundBinaryTag.builder() - .putString("name", name.toString()) - .putInt("id", id) - .put("element", toNBT()) - .build(); + public @NotNull RegistryDataPacket.Entry toRegistryEntry() { + return new RegistryDataPacket.Entry(name.toString(), toNBT()); } @NotNull diff --git a/src/main/java/net/minestom/server/world/DimensionTypeManager.java b/src/main/java/net/minestom/server/world/DimensionTypeManager.java index 4627851f3..181dc5c03 100644 --- a/src/main/java/net/minestom/server/world/DimensionTypeManager.java +++ b/src/main/java/net/minestom/server/world/DimensionTypeManager.java @@ -1,8 +1,8 @@ package net.minestom.server.world; -import net.kyori.adventure.nbt.BinaryTagTypes; -import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.kyori.adventure.nbt.ListBinaryTag; +import net.minestom.server.network.packet.server.CachedPacket; +import net.minestom.server.network.packet.server.SendablePacket; +import net.minestom.server.network.packet.server.configuration.RegistryDataPacket; import net.minestom.server.utils.NamespaceID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,6 +18,7 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public final class DimensionTypeManager { + private final CachedPacket registryDataPacket = new CachedPacket(this::createRegistryDataPacket); private final List dimensionTypes = new CopyOnWriteArrayList<>(); public DimensionTypeManager() { @@ -32,6 +33,7 @@ public final class DimensionTypeManager { public void addDimension(@NotNull DimensionType dimensionType) { dimensionType.registered = true; this.dimensionTypes.add(dimensionType); + registryDataPacket.invalidate(); } /** @@ -42,7 +44,9 @@ public final class DimensionTypeManager { */ public boolean removeDimension(@NotNull DimensionType dimensionType) { dimensionType.registered = false; - return dimensionTypes.remove(dimensionType); + boolean removed = dimensionTypes.remove(dimensionType); + if (removed) registryDataPacket.invalidate(); + return removed; } /** @@ -80,20 +84,16 @@ public final class DimensionTypeManager { return Collections.unmodifiableList(dimensionTypes); } - /** - * Creates the {@link CompoundBinaryTag} containing all the registered dimensions. - *

- * Used when a player connects. - * - * @return an nbt compound containing the registered dimensions - */ - public @NotNull CompoundBinaryTag toNBT() { - ListBinaryTag.Builder entries = ListBinaryTag.builder(BinaryTagTypes.COMPOUND); - for (DimensionType dimensionType : dimensionTypes) - entries.add(dimensionType.toIndexedNBT()); - return CompoundBinaryTag.builder() - .putString("type", "minecraft:dimension_type") - .put("value", entries.build()) - .build(); + public @NotNull SendablePacket registryDataPacket() { + return registryDataPacket; + } + + private @NotNull RegistryDataPacket createRegistryDataPacket() { + return new RegistryDataPacket( + "minecraft:dimension_type", + dimensionTypes.stream() + .map(DimensionType::toRegistryEntry) + .toList() + ); } } diff --git a/src/main/java/net/minestom/server/world/biomes/Biome.java b/src/main/java/net/minestom/server/world/biomes/Biome.java index 0372d6e03..9f43b0cb5 100644 --- a/src/main/java/net/minestom/server/world/biomes/Biome.java +++ b/src/main/java/net/minestom/server/world/biomes/Biome.java @@ -2,6 +2,7 @@ package net.minestom.server.world.biomes; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.coordinate.Point; +import net.minestom.server.network.packet.server.configuration.RegistryDataPacket; import net.minestom.server.registry.ProtocolObject; import net.minestom.server.registry.Registry; import net.minestom.server.utils.NamespaceID; @@ -53,6 +54,10 @@ sealed public interface Biome extends ProtocolObject permits BiomeImpl { } } + default @NotNull RegistryDataPacket.Entry toRegistryEntry() { + return new RegistryDataPacket.Entry(namespace().toString(), toNbt()); + } + default @NotNull CompoundBinaryTag toNbt() { Check.notNull(name(), "The biome namespace cannot be null"); Check.notNull(effects(), "The biome effects cannot be null"); diff --git a/src/main/java/net/minestom/server/world/biomes/BiomeManager.java b/src/main/java/net/minestom/server/world/biomes/BiomeManager.java index 9569ca9f6..2a787db0c 100644 --- a/src/main/java/net/minestom/server/world/biomes/BiomeManager.java +++ b/src/main/java/net/minestom/server/world/biomes/BiomeManager.java @@ -1,8 +1,8 @@ package net.minestom.server.world.biomes; -import net.kyori.adventure.nbt.BinaryTagTypes; -import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.kyori.adventure.nbt.ListBinaryTag; +import net.minestom.server.network.packet.server.CachedPacket; +import net.minestom.server.network.packet.server.SendablePacket; +import net.minestom.server.network.packet.server.configuration.RegistryDataPacket; import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; @@ -10,9 +10,10 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.CopyOnWriteArrayList; /** @@ -20,12 +21,13 @@ import java.util.concurrent.atomic.AtomicInteger; *

*/ public final class BiomeManager { - private final Map biomes = new ConcurrentHashMap<>(); + private final CachedPacket registryDataPacket = new CachedPacket(this::createRegistryDataPacket); + + private final List biomes = new CopyOnWriteArrayList<>(); private final Map biomesByName = new ConcurrentHashMap<>(); private final Map idMappings = new ConcurrentHashMap<>(); private final AtomicInteger ID_COUNTER = new AtomicInteger(0); - private CompoundBinaryTag nbtCache = null; public BiomeManager() { // Need to register plains for the client to work properly @@ -48,27 +50,28 @@ public final class BiomeManager { public void addBiome(@NotNull Biome biome) { Check.stateCondition(getByName(biome.namespace()) != null, "The biome " + biome.namespace() + " has already been registered"); - var id = ID_COUNTER.getAndIncrement(); - this.biomes.put(id, biome); + var id = this.biomes.size(); + this.biomes.add(biome); this.biomesByName.put(biome.namespace(), biome); this.idMappings.put(biome.namespace(), id); - nbtCache = null; + registryDataPacket.invalidate(); } - /** - * Removes a biome. This does NOT send the new list to players. - * - * @param biome the biome to remove - */ - public void removeBiome(@NotNull Biome biome) { - var id = idMappings.get(biome.namespace()); - if (id != null) { - biomes.remove(id); - biomesByName.remove(biome.namespace()); - idMappings.remove(biome.namespace()); - nbtCache = null; - } - } + //todo supporting remove is probably challenging at best since we no longer send ids explicitly, so you cannot skip an ID. +// /** +// * Removes a biome. This does NOT send the new list to players. +// * +// * @param biome the biome to remove +// */ +// public void removeBiome(@NotNull Biome biome) { +// var id = idMappings.get(biome.namespace()); +// if (id != null) { +// biomes.remove(id.intValue()); +// biomesByName.remove(biome.namespace()); +// idMappings.remove(biome.namespace()); +// registryDataPacket.invalidate(); +// } +// } /** * Returns an immutable copy of the biomes already registered. @@ -76,7 +79,7 @@ public final class BiomeManager { * @return an immutable copy of the biomes already registered */ public Collection unmodifiableCollection() { - return Collections.unmodifiableCollection(biomes.values()); + return Collections.unmodifiableCollection(biomes); } /** @@ -101,24 +104,6 @@ public final class BiomeManager { return getByName(namespace); } - public @NotNull CompoundBinaryTag toNBT() { - if (nbtCache != null) return nbtCache; - - ListBinaryTag.Builder entries = ListBinaryTag.builder(BinaryTagTypes.COMPOUND); - for (Biome biome : biomes.values()) { - entries.add(CompoundBinaryTag.builder() - .putInt("id", getId(biome)) - .putString("name", biome.namespace().toString()) - .put("element", biome.toNbt()) - .build()); - } - nbtCache = CompoundBinaryTag.builder() - .putString("type", "minecraft:worldgen/biome") - .put("value", entries.build()) - .build(); - return nbtCache; - } - /** * Gets the id of a biome. *` @@ -128,4 +113,32 @@ public final class BiomeManager { public int getId(Biome biome) { return idMappings.getOrDefault(biome.namespace(), -1); } +// +// public @NotNull NBTCompound toNBT() { +// if (nbtCache != null) return nbtCache; +// nbtCache = NBT.Compound(Map.of( +// "type", NBT.String("minecraft:worldgen/biome"), +// "value", NBT.List(NBTType.TAG_Compound, biomes.values().stream().map(biome -> { +// return NBT.Compound(Map.of( +// "id", NBT.Int(getId(biome)), +// "name", NBT.String(biome.namespace().toString()), +// "element", biome.toNbt() +// )); +// }).toList()))); +// +// return nbtCache; +// } + + public @NotNull SendablePacket registryDataPacket() { + return registryDataPacket; + } + + private @NotNull RegistryDataPacket createRegistryDataPacket() { + return new RegistryDataPacket( + "minecraft:worldgen/biome", + biomes.stream() + .map(Biome::toRegistryEntry) + .toList() + ); + } } diff --git a/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java index d4bc0029e..ce434dd34 100644 --- a/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java @@ -1,10 +1,10 @@ package net.minestom.server.entity; import net.kyori.adventure.text.Component; -import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.network.packet.server.play.EntityMetaDataPacket; +import net.minestom.testing.Env; +import net.minestom.testing.EnvTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -105,7 +105,7 @@ public class EntityMetaIntegrationTest { //This is first test, and it is not related to "custom name" bug. Therefore, it should work. var packets = incomingPackets.collect(); validMetaDataPackets(packets, entity.getEntityId(), entry -> { - if (entry.type() != Metadata.TYPE_OPTCHAT) return; + if (entry.type() != Metadata.TYPE_OPT_CHAT) return; assertEquals(Component.text("Custom Name"), entry.value()); }); @@ -127,7 +127,7 @@ public class EntityMetaIntegrationTest { //Listen packets to check if entity name is "Custom Name 2". packets = incomingPackets.collect(); validMetaDataPackets(packets, entity.getEntityId(), entry -> { - if (entry.type() != Metadata.TYPE_OPTCHAT) return; + if (entry.type() != Metadata.TYPE_OPT_CHAT) return; assertEquals(Component.text("Custom Name 2"), entry.value()); }); } diff --git a/src/test/java/net/minestom/server/entity/player/PlayerIntegrationTest.java b/src/test/java/net/minestom/server/entity/player/PlayerIntegrationTest.java index 227dc8813..c96fefddb 100644 --- a/src/test/java/net/minestom/server/entity/player/PlayerIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/player/PlayerIntegrationTest.java @@ -23,7 +23,6 @@ import java.time.Duration; import java.util.ArrayList; import java.util.List; -import static net.minestom.server.entity.Player.*; import static org.junit.jupiter.api.Assertions.*; @EnvTest @@ -119,7 +118,7 @@ public class PlayerIntegrationTest { final var packets = List.of( JoinGamePacket.class, ServerDifficultyPacket.class, SpawnPositionPacket.class, - DeclareCommandsPacket.class, EntityPropertiesPacket.class, EntityStatusPacket.class, + DeclareCommandsPacket.class, EntityAttributesPacket.class, EntityStatusPacket.class, UpdateHealthPacket.class, PlayerAbilitiesPacket.class ); final List> trackers = new ArrayList<>(); diff --git a/src/test/java/net/minestom/server/item/ItemAttributeTest.java b/src/test/java/net/minestom/server/item/ItemAttributeTest.java index 4111ba131..f7c8d82a3 100644 --- a/src/test/java/net/minestom/server/item/ItemAttributeTest.java +++ b/src/test/java/net/minestom/server/item/ItemAttributeTest.java @@ -1,13 +1,10 @@ package net.minestom.server.item; import net.minestom.server.attribute.Attribute; -import net.minestom.server.attribute.AttributeOperation; +import net.minestom.server.entity.attribute.AttributeOperation; import net.minestom.server.item.attribute.AttributeSlot; import net.minestom.server.item.attribute.ItemAttribute; import net.minestom.server.tag.TagHandler; -import net.minestom.server.tag.TagWritable; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.junit.jupiter.api.Test; import java.util.List; diff --git a/src/test/java/net/minestom/server/network/PacketWriteReadTest.java b/src/test/java/net/minestom/server/network/PacketWriteReadTest.java index 0e5fe3594..4d4df24c6 100644 --- a/src/test/java/net/minestom/server/network/PacketWriteReadTest.java +++ b/src/test/java/net/minestom/server/network/PacketWriteReadTest.java @@ -1,12 +1,8 @@ package net.minestom.server.network; import com.google.gson.JsonObject; - -import java.io.PrintStream; - import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.text.Component; -import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.entity.GameMode; @@ -140,7 +136,7 @@ public class PacketWriteReadTest { SERVER_PACKETS.add(new EntityMetaDataPacket(5, Map.of(1, Metadata.VarInt(5)))); SERVER_PACKETS.add(new EntityPositionAndRotationPacket(5, (short) 0, (short) 0, (short) 0, 45f, 45f, false)); SERVER_PACKETS.add(new EntityPositionPacket(5, (short) 0, (short) 0, (short) 0, true)); - SERVER_PACKETS.add(new EntityPropertiesPacket(5, List.of())); + SERVER_PACKETS.add(new EntityAttributesPacket(5, List.of())); SERVER_PACKETS.add(new EntityRotationPacket(5, 45f, 45f, false)); final PlayerSkin skin = new PlayerSkin("hh", "hh");