From 6345042aa6121d00a87882c4c4dbb2e090b7fc5b Mon Sep 17 00:00:00 2001 From: mworzala Date: Wed, 12 Jun 2024 11:50:27 -0400 Subject: [PATCH] chore: protocol set --- .../java/net/minestom/server/ServerFlag.java | 1 + .../server/component/DataComponentMap.java | 40 ++++++++--- .../minestom/server/item/ItemComponent.java | 6 ++ .../net/minestom/server/item/ItemStack.java | 4 +- .../minestom/server/item/ItemStackImpl.java | 4 +- .../enchant/EnchantmentEffectComponent.java | 69 ++++++++++--------- .../server/item/enchant/EnchantmentImpl.java | 3 +- .../server/registry/DynamicRegistryImpl.java | 8 +++ .../server/registry/ProtocolObject.java | 11 +++ 9 files changed, 96 insertions(+), 50 deletions(-) diff --git a/src/main/java/net/minestom/server/ServerFlag.java b/src/main/java/net/minestom/server/ServerFlag.java index 94e612e3a..e685ddf9c 100644 --- a/src/main/java/net/minestom/server/ServerFlag.java +++ b/src/main/java/net/minestom/server/ServerFlag.java @@ -49,6 +49,7 @@ public final class ServerFlag { public static final @Nullable String MAP_RGB_REDUCTION = System.getProperty("minestom.map.rgbreduction"); // Only used if rgb mapping is "approximate" // Experimental/Unstable + public static final boolean REGISTRY_LATE_REGISTER = Boolean.getBoolean("minestom.registry.late-register"); public static final boolean REGISTRY_UNSAFE_OPS = Boolean.getBoolean("minestom.registry.unsafe-ops"); public static final boolean EVENT_NODE_ALLOW_MULTIPLE_PARENTS = Boolean.getBoolean("minestom.event.multiple-parents"); diff --git a/src/main/java/net/minestom/server/component/DataComponentMap.java b/src/main/java/net/minestom/server/component/DataComponentMap.java index 1fdc72036..64837189e 100644 --- a/src/main/java/net/minestom/server/component/DataComponentMap.java +++ b/src/main/java/net/minestom/server/component/DataComponentMap.java @@ -17,26 +17,44 @@ import org.jetbrains.annotations.Nullable; public sealed interface DataComponentMap extends DataComponent.Holder permits DataComponentMapImpl { @NotNull DataComponentMap EMPTY = new DataComponentMapImpl(new Int2ObjectArrayMap<>(0)); - static @NotNull NetworkBuffer.Type networkType(@NotNull NetworkBuffer.Type> type) { - - } - - static @NotNull BinaryTagSerializer nbtType(@NotNull BinaryTagSerializer> type) { - - } - static @NotNull DataComponentMap.Builder builder() { return new DataComponentMapImpl.BuilderImpl(new Int2ObjectArrayMap<>(), false); } + static @NotNull DataComponentMap.PatchBuilder patchBuilder() { + return new DataComponentMapImpl.BuilderImpl(new Int2ObjectArrayMap<>(), true); + } + + /** + * Creates a network type for the given component type. For internal use only, get the value from the target component class. + */ + @ApiStatus.Internal + static @NotNull NetworkBuffer.Type networkType(@NotNull NetworkBuffer.Type> type) { + + } + + /** + * Creates a network type for the given component type. For internal use only, get the value from the target component class. + */ + @ApiStatus.Internal + static @NotNull BinaryTagSerializer nbtType(@NotNull BinaryTagSerializer> type) { + + } + + /** + * Creates a network type for the given component type. For internal use only, get the value from the target component class. + */ + @ApiStatus.Internal static @NotNull NetworkBuffer.Type patchNetworkType(@NotNull NetworkBuffer.Type> type) { } - static @NotNull BinaryTagSerializer patchNbtType(@NotNull BinaryTagSerializer> type) + /** + * Creates a network type for the given component type. For internal use only, get the value from the target component class. + */ + @ApiStatus.Internal + static @NotNull BinaryTagSerializer patchNbtType(@NotNull BinaryTagSerializer> type) { - static @NotNull DataComponentMap.PatchBuilder patchBuilder() { - return new DataComponentMapImpl.BuilderImpl(new Int2ObjectArrayMap<>(), true); } static @NotNull DataComponentMap diff(@NotNull DataComponentMap prototype, @NotNull DataComponentMap patch) { diff --git a/src/main/java/net/minestom/server/item/ItemComponent.java b/src/main/java/net/minestom/server/item/ItemComponent.java index dde830103..74a060475 100644 --- a/src/main/java/net/minestom/server/item/ItemComponent.java +++ b/src/main/java/net/minestom/server/item/ItemComponent.java @@ -5,6 +5,7 @@ import net.kyori.adventure.util.RGBLike; import net.minestom.server.color.Color; import net.minestom.server.color.DyeColor; import net.minestom.server.component.DataComponent; +import net.minestom.server.component.DataComponentMap; import net.minestom.server.item.component.*; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.utils.NamespaceID; @@ -84,6 +85,11 @@ public final class ItemComponent { public static final DataComponent LOCK = register("lock", null, BinaryTagSerializer.STRING); public static final DataComponent CONTAINER_LOOT = register("container_loot", null, SeededContainerLoot.NBT_TYPE); + private static final NetworkBuffer.Type> COMPONENT_NETWORK_TYPE = NetworkBuffer.VAR_INT.map(ItemComponent::fromId, DataComponent::id); + private static final BinaryTagSerializer> COMPONENT_NBT_TYPE = BinaryTagSerializer.STRING.map(ItemComponent::fromNamespaceId, DataComponent::name); + + public static final NetworkBuffer.Type PATCH_NETWORK_TYPE = DataComponentMap.patchNetworkType(COMPONENT_NETWORK_TYPE); + public static final BinaryTagSerializer PATCH_NBT_TYPE = DataComponentMap.patchNbtType(COMPONENT_NBT_TYPE); public static @Nullable DataComponent fromNamespaceId(@NotNull String namespaceId) { return NAMESPACES.get(namespaceId); diff --git a/src/main/java/net/minestom/server/item/ItemStack.java b/src/main/java/net/minestom/server/item/ItemStack.java index 570e54c58..1ca75b1ba 100644 --- a/src/main/java/net/minestom/server/item/ItemStack.java +++ b/src/main/java/net/minestom/server/item/ItemStack.java @@ -43,7 +43,7 @@ public sealed interface ItemStack extends TagReadable, DataComponent.Holder, Hov buffer.write(NetworkBuffer.VAR_INT, value.amount()); buffer.write(NetworkBuffer.VAR_INT, value.material().id()); - buffer.write(DataComponentMap.PATCH_NETWORK_TYPE, ((ItemStackImpl) value).components()); + buffer.write(ItemComponent.PATCH_NETWORK_TYPE, ((ItemStackImpl) value).components()); } @Override @@ -51,7 +51,7 @@ public sealed interface ItemStack extends TagReadable, DataComponent.Holder, Hov int amount = buffer.read(NetworkBuffer.VAR_INT); if (amount <= 0) return ItemStack.AIR; Material material = Material.fromId(buffer.read(NetworkBuffer.VAR_INT)); - DataComponentMap components = buffer.read(DataComponentMap.PATCH_NETWORK_TYPE); + DataComponentMap components = buffer.read(ItemComponent.PATCH_NETWORK_TYPE); return ItemStackImpl.create(material, amount, components); } }; diff --git a/src/main/java/net/minestom/server/item/ItemStackImpl.java b/src/main/java/net/minestom/server/item/ItemStackImpl.java index e29f1be35..0ae74b179 100644 --- a/src/main/java/net/minestom/server/item/ItemStackImpl.java +++ b/src/main/java/net/minestom/server/item/ItemStackImpl.java @@ -104,7 +104,7 @@ record ItemStackImpl(Material material, int amount, DataComponentMap components) Material material = Material.fromNamespaceId(id); Check.notNull(material, "Unknown material: {0}", id); int count = tag.getInt("count", 1); - DataComponentMap patch = DataComponentMap.PATCH_NBT_TYPE.read(tag.getCompound("components")); + DataComponentMap patch = ItemComponent.PATCH_NBT_TYPE.read(tag.getCompound("components")); return new ItemStackImpl(material, count, patch); } @@ -113,7 +113,7 @@ record ItemStackImpl(Material material, int amount, DataComponentMap components) tag.putString("id", itemStack.material().name()); tag.putInt("count", itemStack.amount()); - CompoundBinaryTag components = (CompoundBinaryTag) DataComponentMap.PATCH_NBT_TYPE.write(((ItemStackImpl) itemStack).components); + CompoundBinaryTag components = (CompoundBinaryTag) ItemComponent.PATCH_NBT_TYPE.write(((ItemStackImpl) itemStack).components); if (components.size() > 0) tag.put("components", components); return tag.build(); diff --git a/src/main/java/net/minestom/server/item/enchant/EnchantmentEffectComponent.java b/src/main/java/net/minestom/server/item/enchant/EnchantmentEffectComponent.java index 7a7340453..9b170c1d4 100644 --- a/src/main/java/net/minestom/server/item/enchant/EnchantmentEffectComponent.java +++ b/src/main/java/net/minestom/server/item/enchant/EnchantmentEffectComponent.java @@ -1,7 +1,7 @@ package net.minestom.server.item.enchant; import net.minestom.server.component.DataComponent; -import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.component.DataComponentMap; import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.Unit; import net.minestom.server.utils.collection.ObjectArray; @@ -17,37 +17,40 @@ public class EnchantmentEffectComponent { static final Map> NAMESPACES = new HashMap<>(32); static final ObjectArray> IDS = ObjectArray.singleThread(32); - public static final DataComponent DAMAGE_PROTECTION = register("damage_protection", null, null); //todo - public static final DataComponent DAMAGE_IMMUNITY = register("damage_immunity", null, null); //todo - public static final DataComponent DAMAGE = register("damage", null, null); //todo - public static final DataComponent SMASH_DAMAGE_PER_FALLEN_BLOCK = register("smash_damage_per_fallen_block", null, null); //todo - public static final DataComponent KNOCKBACK = register("knockback", null, null); //todo - public static final DataComponent ARMOR_EFFECTIVENESS = register("armor_effectiveness", null, null); //todo - public static final DataComponent POST_ATTACK = register("post_attack", null, null); //todo - public static final DataComponent HIT_BLOCK = register("hit_block", null, null); //todo - public static final DataComponent ITEM_DAMAGE = register("item_damage", null, null); //todo - public static final DataComponent ATTRIBUTES = register("attributes", null, null); //todo - public static final DataComponent EQUIPMENT_DROPS = register("equipment_drops", null, null); //todo - public static final DataComponent LOCATION_CHANGED = register("location_changed", null, null); //todo - public static final DataComponent TICK = register("tick", null, null); //todo - public static final DataComponent AMMO_USE = register("ammo_use", null, null); //todo - public static final DataComponent PROJECTILE_PIERCING = register("projectile_piercing", null, null); //todo - public static final DataComponent PROJECTILE_SPAWNED = register("projectile_spawned", null, null); //todo - public static final DataComponent PROJECTILE_SPREAD = register("projectile_spread", null, null); //todo - public static final DataComponent PROJECTILE_COUNT = register("projectile_count", null, null); //todo - public static final DataComponent TRIDENT_RETURN_ACCELERATION = register("trident_return_acceleration", null, null); //todo - public static final DataComponent FISHING_TIME_REDUCTION = register("fishing_time_reduction", null, null); //todo - public static final DataComponent FISHING_LUCK_BONUS = register("fishing_luck_bonus", null, null); //todo - public static final DataComponent BLOCK_EXPERIENCE = register("block_experience", null, null); //todo - public static final DataComponent MOB_EXPERIENCE = register("mob_experience", null, null); //todo - public static final DataComponent REPAIR_WITH_XP = register("repair_with_xp", null, null); //todo - public static final DataComponent CROSSBOW_CHARGE_TIME = register("crossbow_charge_time", null, null); //todo - public static final DataComponent CROSSBOW_CHARGING_SOUNDS = register("crossbow_charging_sounds", null, null); //todo - public static final DataComponent TRIDENT_SOUND = register("trident_sound", null, null); //todo - public static final DataComponent PREVENT_EQUIPMENT_DROP = register("prevent_equipment_drop", null, null); //todo - public static final DataComponent PREVENT_ARMOR_CHANGE = register("prevent_armor_change", null, null); //todo - public static final DataComponent TRIDENT_SPIN_ATTACK_STRENGTH = register("trident_spin_attack_strength", null, null); //todo + public static final DataComponent DAMAGE_PROTECTION = register("damage_protection", null); //todo + public static final DataComponent DAMAGE_IMMUNITY = register("damage_immunity", null); //todo + public static final DataComponent DAMAGE = register("damage", null); //todo + public static final DataComponent SMASH_DAMAGE_PER_FALLEN_BLOCK = register("smash_damage_per_fallen_block", null); //todo + public static final DataComponent KNOCKBACK = register("knockback", null); //todo + public static final DataComponent ARMOR_EFFECTIVENESS = register("armor_effectiveness", null); //todo + public static final DataComponent POST_ATTACK = register("post_attack", null); //todo + public static final DataComponent HIT_BLOCK = register("hit_block", null); //todo + public static final DataComponent ITEM_DAMAGE = register("item_damage", null); //todo + public static final DataComponent ATTRIBUTES = register("attributes", null); //todo + public static final DataComponent EQUIPMENT_DROPS = register("equipment_drops", null); //todo + public static final DataComponent LOCATION_CHANGED = register("location_changed", null); //todo + public static final DataComponent TICK = register("tick", null); //todo + public static final DataComponent AMMO_USE = register("ammo_use", null); //todo + public static final DataComponent PROJECTILE_PIERCING = register("projectile_piercing", null); //todo + public static final DataComponent PROJECTILE_SPAWNED = register("projectile_spawned", null); //todo + public static final DataComponent PROJECTILE_SPREAD = register("projectile_spread", null); //todo + public static final DataComponent PROJECTILE_COUNT = register("projectile_count", null); //todo + public static final DataComponent TRIDENT_RETURN_ACCELERATION = register("trident_return_acceleration", null); //todo + public static final DataComponent FISHING_TIME_REDUCTION = register("fishing_time_reduction", null); //todo + public static final DataComponent FISHING_LUCK_BONUS = register("fishing_luck_bonus", null); //todo + public static final DataComponent BLOCK_EXPERIENCE = register("block_experience", null); //todo + public static final DataComponent MOB_EXPERIENCE = register("mob_experience", null); //todo + public static final DataComponent REPAIR_WITH_XP = register("repair_with_xp", null); //todo + public static final DataComponent CROSSBOW_CHARGE_TIME = register("crossbow_charge_time", null); //todo + public static final DataComponent CROSSBOW_CHARGING_SOUNDS = register("crossbow_charging_sounds", null); //todo + public static final DataComponent TRIDENT_SOUND = register("trident_sound", null); //todo + public static final DataComponent PREVENT_EQUIPMENT_DROP = register("prevent_equipment_drop", null); //todo + public static final DataComponent PREVENT_ARMOR_CHANGE = register("prevent_armor_change", null); //todo + public static final DataComponent TRIDENT_SPIN_ATTACK_STRENGTH = register("trident_spin_attack_strength", null); //todo + private static final BinaryTagSerializer> COMPONENT_NBT_TYPE = BinaryTagSerializer.STRING.map(EnchantmentEffectComponent::fromNamespaceId, DataComponent::name); + + public static final BinaryTagSerializer NBT_TYPE = DataComponentMap.nbtType(COMPONENT_NBT_TYPE); public static @Nullable DataComponent fromNamespaceId(@NotNull String namespaceId) { return NAMESPACES.get(namespaceId); @@ -65,8 +68,8 @@ public class EnchantmentEffectComponent { return NAMESPACES.values(); } - static DataComponent register(@NotNull String name, @Nullable NetworkBuffer.Type network, @Nullable BinaryTagSerializer nbt) { - DataComponent impl = DataComponent.createHeadless(NAMESPACES.size(), NamespaceID.from(name), network, nbt); + static DataComponent register(@NotNull String name, @Nullable BinaryTagSerializer nbt) { + DataComponent impl = DataComponent.createHeadless(NAMESPACES.size(), NamespaceID.from(name), null, nbt); NAMESPACES.put(impl.name(), impl); IDS.set(impl.id(), impl); return impl; diff --git a/src/main/java/net/minestom/server/item/enchant/EnchantmentImpl.java b/src/main/java/net/minestom/server/item/enchant/EnchantmentImpl.java index 357ab5c3a..23329420b 100644 --- a/src/main/java/net/minestom/server/item/enchant/EnchantmentImpl.java +++ b/src/main/java/net/minestom/server/item/enchant/EnchantmentImpl.java @@ -46,8 +46,7 @@ record EnchantmentImpl( .put("max_cost", Cost.NBT_TYPE.write(value.maxCost())) .putInt("anvil_cost", value.anvilCost()) .put("slots", SLOTS_NBT_TYPE.write(value.slots())) -// .put("effects", ) - //todo effects + .put("effects", EnchantmentEffectComponent.NBT_TYPE.write(value.effects())) .build() ); diff --git a/src/main/java/net/minestom/server/registry/DynamicRegistryImpl.java b/src/main/java/net/minestom/server/registry/DynamicRegistryImpl.java index ca4a39bd5..5bdb18d4b 100644 --- a/src/main/java/net/minestom/server/registry/DynamicRegistryImpl.java +++ b/src/main/java/net/minestom/server/registry/DynamicRegistryImpl.java @@ -1,12 +1,14 @@ package net.minestom.server.registry; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minestom.server.MinecraftServer; import net.minestom.server.ServerFlag; 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.nbt.BinaryTagSerializer; +import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -104,6 +106,12 @@ final class DynamicRegistryImpl implements DynamicRegi @Override public @NotNull DynamicRegistry.Key register(@NotNull T object) { + Check.stateCondition(MinecraftServer.isStarted() && !ServerFlag.REGISTRY_LATE_REGISTER, + "Registering an object to a dynamic registry ({0}) after the server is started can lead to " + + "registry desync between the client and server. This is usually unwanted behavior. If you " + + "know what you're doing and would like this behavior, set the `minestom.registry.late-register` " + + "system property.", id); + lock.lock(); try { int id = idByName.indexOf(object.namespace()); diff --git a/src/main/java/net/minestom/server/registry/ProtocolObject.java b/src/main/java/net/minestom/server/registry/ProtocolObject.java index 984c8c1e8..7b3a6f34b 100644 --- a/src/main/java/net/minestom/server/registry/ProtocolObject.java +++ b/src/main/java/net/minestom/server/registry/ProtocolObject.java @@ -9,6 +9,17 @@ import org.jetbrains.annotations.Nullable; public interface ProtocolObject extends Keyed { + /** + * A set of some protocol objects. May contain a single element, multiple elements, or a single tag (which itself contains multiple elements). + * + * @param The type of protocol object represented by this set. + */ + interface Set { + + + + } + @Contract(pure = true) @NotNull NamespaceID namespace();