mirror of https://github.com/Minestom/Minestom.git
feat: joinable server
This commit is contained in:
parent
e3f4d8a6cf
commit
c7a7c790c0
|
@ -24,6 +24,7 @@ allprojects {
|
|||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven(url = "https://jitpack.io")
|
||||
}
|
||||
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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<JavaFile> filesToWrite = new ArrayList<>();
|
||||
|
||||
ClassName attributeClassName = ClassName.get("net.minestom.server.attribute", "Attribute");
|
||||
|
||||
// Attribute
|
||||
TypeSpec.Builder attributeClass = TypeSpec.classBuilder(attributeClassName)
|
||||
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
|
||||
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
|
||||
attributeClass.addField(
|
||||
FieldSpec.builder(namespaceIDClassName, "id")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
|
||||
);
|
||||
attributeClass.addField(
|
||||
FieldSpec.builder(TypeName.DOUBLE, "defaultValue")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
|
||||
);
|
||||
attributeClass.addField(
|
||||
FieldSpec.builder(TypeName.BOOLEAN, "clientSyncable")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
|
||||
);
|
||||
attributeClass.addMethod(
|
||||
MethodSpec.constructorBuilder()
|
||||
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
|
||||
.addParameter(ParameterSpec.builder(TypeName.BOOLEAN, "clientSyncable").build())
|
||||
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "defaultValue").build())
|
||||
.addStatement("this.id = id")
|
||||
.addStatement("this.clientSyncable = clientSyncable")
|
||||
.addStatement("this.defaultValue = defaultValue")
|
||||
.addModifiers(Modifier.PROTECTED)
|
||||
.build()
|
||||
);
|
||||
// Override key method (adventure)
|
||||
attributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("key")
|
||||
.returns(ClassName.get("net.kyori.adventure.key", "Key"))
|
||||
.addAnnotation(Override.class)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addStatement("return this.id")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// getId method
|
||||
attributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("getId")
|
||||
.returns(namespaceIDClassName)
|
||||
.addAnnotation(NotNull.class)
|
||||
.addStatement("return this.id")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// getDefaultValue
|
||||
attributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("getDefaultValue")
|
||||
.returns(TypeName.DOUBLE)
|
||||
.addStatement("return this.defaultValue")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// isClientSyncable
|
||||
attributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("isClientSyncable")
|
||||
.returns(TypeName.BOOLEAN)
|
||||
.addStatement("return this.clientSyncable")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// isShared
|
||||
attributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("isShared")
|
||||
.addAnnotation(Deprecated.class)
|
||||
.returns(TypeName.BOOLEAN)
|
||||
.addStatement("return this.clientSyncable")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// values method
|
||||
attributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("values")
|
||||
.addAnnotation(NotNull.class)
|
||||
.returns(ParameterizedTypeName.get(ClassName.get(List.class), attributeClassName))
|
||||
.addStatement("return $T.ATTRIBUTE_REGISTRY.values()", registryClassName)
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.build()
|
||||
);
|
||||
// toString method
|
||||
attributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("toString")
|
||||
.addAnnotation(NotNull.class)
|
||||
.addAnnotation(Override.class)
|
||||
.returns(String.class)
|
||||
// this resolves to [Namespace]
|
||||
.addStatement("return \"[\" + this.id + \"]\"")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// Creating ClampedAttribute
|
||||
ClassName clampedAttributeClassName = ClassName.get("net.minestom.server.attribute", "ClampedAttribute");
|
||||
|
||||
TypeSpec.Builder clampedAttributeClass = TypeSpec.classBuilder(clampedAttributeClassName)
|
||||
.superclass(attributeClassName)
|
||||
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
|
||||
clampedAttributeClass.addField(
|
||||
FieldSpec.builder(TypeName.DOUBLE, "minValue")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
|
||||
);
|
||||
clampedAttributeClass.addField(
|
||||
FieldSpec.builder(TypeName.DOUBLE, "maxValue")
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).build()
|
||||
);
|
||||
clampedAttributeClass.addMethod(
|
||||
MethodSpec.constructorBuilder()
|
||||
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
|
||||
.addParameter(ParameterSpec.builder(TypeName.BOOLEAN, "clientSyncable").build())
|
||||
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "defaultValue").build())
|
||||
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "minValue").build())
|
||||
.addParameter(ParameterSpec.builder(TypeName.DOUBLE, "maxValue").build())
|
||||
.addStatement("super(id, clientSyncable, defaultValue)")
|
||||
.addStatement("this.minValue = minValue")
|
||||
.addStatement("this.maxValue = maxValue")
|
||||
.addModifiers(Modifier.PROTECTED)
|
||||
.build()
|
||||
);
|
||||
// getMinValue
|
||||
clampedAttributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("getMinValue")
|
||||
.returns(TypeName.DOUBLE)
|
||||
.addStatement("return this.minValue")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
// getMaxValue
|
||||
clampedAttributeClass.addMethod(
|
||||
MethodSpec.methodBuilder("getMaxValue")
|
||||
.returns(TypeName.DOUBLE)
|
||||
.addStatement("return this.maxValue")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.build()
|
||||
);
|
||||
|
||||
CodeBlock.Builder staticBlock = CodeBlock.builder();
|
||||
// Use data
|
||||
for (JsonElement a : attributes) {
|
||||
JsonObject attribute = a.getAsJsonObject();
|
||||
String attributeName = attribute.get("name").getAsString();
|
||||
|
||||
JsonObject range = attribute.getAsJsonObject("range");
|
||||
if (range == null) {
|
||||
// Normal attribute
|
||||
attributeClass.addField(
|
||||
FieldSpec.builder(
|
||||
attributeClassName,
|
||||
attributeName
|
||||
).initializer(
|
||||
"new $T($T.from($S), $L, $L)",
|
||||
attributeClassName,
|
||||
namespaceIDClassName,
|
||||
attribute.get("id").getAsString(),
|
||||
attribute.get("clientSync").getAsBoolean(),
|
||||
attribute.get("defaultValue").getAsDouble()
|
||||
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
|
||||
);
|
||||
} else {
|
||||
// ClampedAttribute
|
||||
attributeClass.addField(
|
||||
FieldSpec.builder(
|
||||
attributeClassName,
|
||||
attributeName
|
||||
).initializer(
|
||||
"new $T($T.from($S), $L, $L, $L, $L)",
|
||||
clampedAttributeClassName,
|
||||
namespaceIDClassName,
|
||||
attribute.get("id").getAsString(),
|
||||
attribute.get("clientSync").getAsBoolean(),
|
||||
attribute.get("defaultValue").getAsDouble(),
|
||||
range.get("minValue").getAsDouble(),
|
||||
range.get("maxValue").getAsDouble()
|
||||
).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build()
|
||||
);
|
||||
}
|
||||
// Add to static init.
|
||||
staticBlock.addStatement("$T.ATTRIBUTE_REGISTRY.register($N)", registryClassName, attributeName);
|
||||
}
|
||||
attributeClass.addStaticBlock(staticBlock.build());
|
||||
|
||||
filesToWrite.add(
|
||||
JavaFile.builder("net.minestom.server.attribute", attributeClass.build())
|
||||
.indent(" ")
|
||||
.skipJavaLangImports(true)
|
||||
.build()
|
||||
);
|
||||
filesToWrite.add(
|
||||
JavaFile.builder("net.minestom.server.attribute", clampedAttributeClass.build())
|
||||
.indent(" ")
|
||||
.skipJavaLangImports(true)
|
||||
.build()
|
||||
);
|
||||
|
||||
// Write files to outputFolder
|
||||
writeFiles(
|
||||
filesToWrite,
|
||||
outputFolder
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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<String, Attribute> 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();
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
* <p>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(byte value) {
|
||||
|
@ -50,11 +49,11 @@ public final class Metadata {
|
|||
}
|
||||
|
||||
public static Entry<Component> 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<ItemStack> Slot(@NotNull ItemStack value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_SLOT, value, NetworkBuffer.ITEM);
|
||||
public static Entry<ItemStack> ItemStack(@NotNull ItemStack value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_ITEM_STACK, value, NetworkBuffer.ITEM);
|
||||
}
|
||||
|
||||
public static Entry<Boolean> Boolean(boolean value) {
|
||||
|
@ -65,12 +64,12 @@ public final class Metadata {
|
|||
return new MetadataImpl.EntryImpl<>(TYPE_ROTATION, value, NetworkBuffer.VECTOR3);
|
||||
}
|
||||
|
||||
public static Entry<Point> Position(@NotNull Point value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_POSITION, value, NetworkBuffer.BLOCK_POSITION);
|
||||
public static Entry<Point> BlockPosition(@NotNull Point value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_BLOCK_POSITION, value, NetworkBuffer.BLOCK_POSITION);
|
||||
}
|
||||
|
||||
public static Entry<Point> OptPosition(@Nullable Point value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_OPTPOSITION, value, NetworkBuffer.OPT_BLOCK_POSITION);
|
||||
public static Entry<Point> OptBlockPosition(@Nullable Point value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_OPT_BLOCK_POSITION, value, NetworkBuffer.OPT_BLOCK_POSITION);
|
||||
}
|
||||
|
||||
public static Entry<Direction> Direction(@NotNull Direction value) {
|
||||
|
@ -78,7 +77,7 @@ public final class Metadata {
|
|||
}
|
||||
|
||||
public static Entry<UUID> 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<Integer> BlockState(@Nullable Integer value) {
|
||||
|
@ -86,22 +85,38 @@ public final class Metadata {
|
|||
}
|
||||
|
||||
public static Entry<Integer> 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<BinaryTag> NBT(@NotNull BinaryTag nbt) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_NBT, nbt, NetworkBuffer.NBT);
|
||||
}
|
||||
|
||||
public static Entry<int[]> VillagerData(int villagerType,
|
||||
int villagerProfession,
|
||||
int level) {
|
||||
public static Entry<Particle> Particle(@NotNull Particle particle) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_PARTICLE, particle, NetworkBuffer.PARTICLE);
|
||||
}
|
||||
|
||||
public static Entry<List<Particle>> ParticleList(@NotNull List<Particle> particles) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_PARTICLE_LIST, particles, new NetworkBuffer.Type<>() {
|
||||
@Override
|
||||
public void write(@NotNull NetworkBuffer buffer, List<Particle> value) {
|
||||
buffer.writeCollection(NetworkBuffer.PARTICLE, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Particle> read(@NotNull NetworkBuffer buffer) {
|
||||
return buffer.readCollection(NetworkBuffer.PARTICLE, Integer.MAX_VALUE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Entry<int[]> VillagerData(int villagerType, int villagerProfession, int level) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_VILLAGERDATA, new int[]{villagerType, villagerProfession, level},
|
||||
NetworkBuffer.VILLAGER_DATA);
|
||||
}
|
||||
|
||||
public static Entry<Integer> 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<FrogMeta.Variant> FrogVariant(@NotNull FrogMeta.Variant value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_FROG_VARIANT, value, NetworkBuffer.FROG_VARIANT);
|
||||
}
|
||||
|
||||
public static Entry<PaintingMeta.Variant> 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<SnifferMeta.State> SnifferState(@NotNull SnifferMeta.State value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_SNIFFER_STATE, value, NetworkBuffer.SNIFFER_STATE);
|
||||
}
|
||||
|
||||
public static Entry<ArmadilloMeta.State> ArmadilloState(@NotNull ArmadilloMeta.State value) {
|
||||
return new MetadataImpl.EntryImpl<>(TYPE_ARMADILLO_STATE, value, NetworkBuffer.ARMADILLO_STATE);
|
||||
}
|
||||
|
||||
public static Entry<Point> 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> 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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<Attribute> 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<Attribute> values() {
|
||||
return CONTAINER.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
}
|
|
@ -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<UUID, AttributeModifier> modifiers = new HashMap<>();
|
||||
private final Consumer<AttributeInstance> propertyChangeListener;
|
||||
private float baseValue;
|
||||
private float cachedValue = 0.0f;
|
||||
private double baseValue;
|
||||
private double cachedValue = 0.0f;
|
||||
|
||||
public AttributeInstance(@NotNull Attribute attribute, @Nullable Consumer<AttributeInstance> 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<AttributeModifier> 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());
|
|
@ -1,4 +1,4 @@
|
|||
package net.minestom.server.attribute;
|
||||
package net.minestom.server.entity.attribute;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package net.minestom.server.attribute;
|
||||
package net.minestom.server.entity.attribute;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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<DamageType> 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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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<Particle> 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<Particle> 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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -12,6 +12,8 @@ public class WolfMeta extends TameableAnimalMeta {
|
|||
super(entity, metadata);
|
||||
}
|
||||
|
||||
//todo variant
|
||||
|
||||
public boolean isBegging() {
|
||||
return super.metadata.getIndex(OFFSET, false);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<CustomData> TAG = Tag.Structure("ab", CustomData.class);
|
||||
|
||||
static final NetworkBuffer.Type<CustomData> 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));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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<CustomData> CUSTOM_DATA = new ItemComponent.Type<>("custom_data", CustomData.NETWORK_TYPE, CustomData.TAG);
|
||||
|
||||
record Type<T extends ItemComponent>(
|
||||
@NotNull String name,
|
||||
@NotNull NetworkBuffer.Type<T> network,
|
||||
@NotNull Tag<T> tag
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -13,7 +13,7 @@ import org.jetbrains.annotations.UnknownNullability;
|
|||
import java.util.List;
|
||||
|
||||
public record PotionMeta(TagReadable readable) implements ItemMetaView<PotionMeta.Builder> {
|
||||
private static final Tag<PotionType> POTION_TYPE = Tag.String("Potion").map(PotionType::fromNamespaceId, StaticProtocolObject::name).defaultValue(PotionType.EMPTY);
|
||||
private static final Tag<PotionType> POTION_TYPE = Tag.String("Potion").map(PotionType::fromNamespaceId, StaticProtocolObject::name).defaultValue(PotionType.WATER);
|
||||
private static final Tag<List<CustomPotionEffect>> CUSTOM_POTION_EFFECTS = Tag.Structure("CustomPotionEffects", new TagSerializer<CustomPotionEffect>() {
|
||||
@Override
|
||||
public @Nullable CustomPotionEffect read(@NotNull TagReadable reader) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<FrogMeta.Variant> FROG_VARIANT = NetworkBufferTypeImpl.fromEnum(FrogMeta.Variant.class);
|
||||
public static final Type<PaintingMeta.Variant> PAINTING_VARIANT = NetworkBufferTypeImpl.fromEnum(PaintingMeta.Variant.class);
|
||||
public static final Type<SnifferMeta.State> SNIFFER_STATE = NetworkBufferTypeImpl.fromEnum(SnifferMeta.State.class);
|
||||
public static final Type<ArmadilloMeta.State> 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<T> {
|
||||
@NotNull T read(@NotNull NetworkBuffer reader);
|
||||
}
|
||||
|
||||
public static byte[] makeArray(@NotNull Consumer<@NotNull NetworkBuffer> writing) {
|
||||
NetworkBuffer writer = new NetworkBuffer();
|
||||
writing.accept(writer);
|
||||
|
|
|
@ -399,32 +399,28 @@ interface NetworkBufferTypeImpl<T> extends NetworkBuffer.Type<T> {
|
|||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
* <p>
|
||||
* 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<Function<NetworkBuffer, ClientPacket>> suppliers = ObjectArray.singleThread(0x10);
|
||||
private final ObjectArray<NetworkBuffer.Reader<ClientPacket>> 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<ClientPacket> packetSupplier) {
|
||||
this.suppliers.set(id, packetSupplier);
|
||||
}
|
||||
|
||||
public @UnknownNullability ClientPacket create(int packetId, @NotNull NetworkBuffer reader) {
|
||||
final Function<NetworkBuffer, ClientPacket> supplier = suppliers.get(packetId);
|
||||
final NetworkBuffer.Reader<ClientPacket> 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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<SelectKnownPacksPacket.Entry> 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<Entry> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<Entry> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -42,8 +42,8 @@ public record DeclareRecipesPacket(@NotNull List<DeclaredRecipe> 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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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<AttributeInstance> properties) implements ServerPacket.Play {
|
||||
public record EntityAttributesPacket(int entityId, List<AttributeInstance> 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<AttributeInstance> 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<AttributeModifier> modifiers = instance.getModifiers();
|
||||
|
@ -60,6 +64,6 @@ public record EntityPropertiesPacket(int entityId, List<AttributeInstance> prope
|
|||
|
||||
@Override
|
||||
public int playId() {
|
||||
return ServerPacketIdentifier.ENTITY_PROPERTIES;
|
||||
return ServerPacketIdentifier.ENTITY_ATTRIBUTES;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<Integer, Metadata.Entry<?>> 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);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,10 @@ import static net.minestom.server.network.NetworkBuffer.*;
|
|||
public record JoinGamePacket(
|
||||
int entityId, boolean isHardcore, List<String> 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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.
|
||||
* <p>
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -57,7 +57,7 @@ public class RecipeManager {
|
|||
case SMITHING_TRIM -> RecipeConversion.smithingTrim((SmithingTrimRecipe) recipe);
|
||||
});
|
||||
}
|
||||
return new DeclareRecipesPacket(entries);
|
||||
return new DeclareRecipesPacket(List.of());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String, Map<String, Object>> load(Resource resource) {
|
||||
Map<String, Map<String, Object>> 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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<DimensionType> 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.
|
||||
* <p>
|
||||
* Used when a player connects.
|
||||
*
|
||||
* @return an nbt compound containing the registered dimensions
|
||||
*/
|
||||
public @NotNull CompoundBinaryTag toNBT() {
|
||||
ListBinaryTag.Builder<CompoundBinaryTag> 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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
|||
* <p>
|
||||
*/
|
||||
public final class BiomeManager {
|
||||
private final Map<Integer, Biome> biomes = new ConcurrentHashMap<>();
|
||||
private final CachedPacket registryDataPacket = new CachedPacket(this::createRegistryDataPacket);
|
||||
|
||||
private final List<Biome> biomes = new CopyOnWriteArrayList<>();
|
||||
private final Map<NamespaceID, Biome> biomesByName = new ConcurrentHashMap<>();
|
||||
private final Map<NamespaceID, Integer> 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<Biome> 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<CompoundBinaryTag> 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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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<Collector<?>> trackers = new ArrayList<>();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue