chore: protocol set

This commit is contained in:
mworzala 2024-06-12 11:50:27 -04:00 committed by Matt Worzala
parent fc2ce0bde2
commit 6345042aa6
9 changed files with 96 additions and 50 deletions

View File

@ -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");

View File

@ -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<DataComponentMap> networkType(@NotNull NetworkBuffer.Type<DataComponent<?>> type) {
}
static @NotNull BinaryTagSerializer<DataComponentMap> nbtType(@NotNull BinaryTagSerializer<DataComponent<?>> 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<DataComponentMap> networkType(@NotNull NetworkBuffer.Type<DataComponent<?>> 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<DataComponentMap> nbtType(@NotNull BinaryTagSerializer<DataComponent<?>> 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<DataComponentMap> patchNetworkType(@NotNull NetworkBuffer.Type<DataComponent<?>> type) {
}
static @NotNull BinaryTagSerializer<DataComponentMap> patchNbtType(@NotNull BinaryTagSerializer<DataComponent<?>> 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<DataComponentMap> patchNbtType(@NotNull BinaryTagSerializer<DataComponent<?>> type) {
static @NotNull DataComponentMap.PatchBuilder patchBuilder() {
return new DataComponentMapImpl.BuilderImpl(new Int2ObjectArrayMap<>(), true);
}
static @NotNull DataComponentMap diff(@NotNull DataComponentMap prototype, @NotNull DataComponentMap patch) {

View File

@ -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<String> LOCK = register("lock", null, BinaryTagSerializer.STRING);
public static final DataComponent<SeededContainerLoot> CONTAINER_LOOT = register("container_loot", null, SeededContainerLoot.NBT_TYPE);
private static final NetworkBuffer.Type<DataComponent<?>> COMPONENT_NETWORK_TYPE = NetworkBuffer.VAR_INT.map(ItemComponent::fromId, DataComponent::id);
private static final BinaryTagSerializer<DataComponent<?>> COMPONENT_NBT_TYPE = BinaryTagSerializer.STRING.map(ItemComponent::fromNamespaceId, DataComponent::name);
public static final NetworkBuffer.Type<DataComponentMap> PATCH_NETWORK_TYPE = DataComponentMap.patchNetworkType(COMPONENT_NETWORK_TYPE);
public static final BinaryTagSerializer<DataComponentMap> PATCH_NBT_TYPE = DataComponentMap.patchNbtType(COMPONENT_NBT_TYPE);
public static @Nullable DataComponent<?> fromNamespaceId(@NotNull String namespaceId) {
return NAMESPACES.get(namespaceId);

View File

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

View File

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

View File

@ -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<String, DataComponent<?>> NAMESPACES = new HashMap<>(32);
static final ObjectArray<DataComponent<?>> IDS = ObjectArray.singleThread(32);
public static final DataComponent<Unit> DAMAGE_PROTECTION = register("damage_protection", null, null); //todo
public static final DataComponent<Unit> DAMAGE_IMMUNITY = register("damage_immunity", null, null); //todo
public static final DataComponent<Unit> DAMAGE = register("damage", null, null); //todo
public static final DataComponent<Unit> SMASH_DAMAGE_PER_FALLEN_BLOCK = register("smash_damage_per_fallen_block", null, null); //todo
public static final DataComponent<Unit> KNOCKBACK = register("knockback", null, null); //todo
public static final DataComponent<Unit> ARMOR_EFFECTIVENESS = register("armor_effectiveness", null, null); //todo
public static final DataComponent<Unit> POST_ATTACK = register("post_attack", null, null); //todo
public static final DataComponent<Unit> HIT_BLOCK = register("hit_block", null, null); //todo
public static final DataComponent<Unit> ITEM_DAMAGE = register("item_damage", null, null); //todo
public static final DataComponent<Unit> ATTRIBUTES = register("attributes", null, null); //todo
public static final DataComponent<Unit> EQUIPMENT_DROPS = register("equipment_drops", null, null); //todo
public static final DataComponent<Unit> LOCATION_CHANGED = register("location_changed", null, null); //todo
public static final DataComponent<Unit> TICK = register("tick", null, null); //todo
public static final DataComponent<Unit> AMMO_USE = register("ammo_use", null, null); //todo
public static final DataComponent<Unit> PROJECTILE_PIERCING = register("projectile_piercing", null, null); //todo
public static final DataComponent<Unit> PROJECTILE_SPAWNED = register("projectile_spawned", null, null); //todo
public static final DataComponent<Unit> PROJECTILE_SPREAD = register("projectile_spread", null, null); //todo
public static final DataComponent<Unit> PROJECTILE_COUNT = register("projectile_count", null, null); //todo
public static final DataComponent<Unit> TRIDENT_RETURN_ACCELERATION = register("trident_return_acceleration", null, null); //todo
public static final DataComponent<Unit> FISHING_TIME_REDUCTION = register("fishing_time_reduction", null, null); //todo
public static final DataComponent<Unit> FISHING_LUCK_BONUS = register("fishing_luck_bonus", null, null); //todo
public static final DataComponent<Unit> BLOCK_EXPERIENCE = register("block_experience", null, null); //todo
public static final DataComponent<Unit> MOB_EXPERIENCE = register("mob_experience", null, null); //todo
public static final DataComponent<Unit> REPAIR_WITH_XP = register("repair_with_xp", null, null); //todo
public static final DataComponent<Unit> CROSSBOW_CHARGE_TIME = register("crossbow_charge_time", null, null); //todo
public static final DataComponent<Unit> CROSSBOW_CHARGING_SOUNDS = register("crossbow_charging_sounds", null, null); //todo
public static final DataComponent<Unit> TRIDENT_SOUND = register("trident_sound", null, null); //todo
public static final DataComponent<Unit> PREVENT_EQUIPMENT_DROP = register("prevent_equipment_drop", null, null); //todo
public static final DataComponent<Unit> PREVENT_ARMOR_CHANGE = register("prevent_armor_change", null, null); //todo
public static final DataComponent<Unit> TRIDENT_SPIN_ATTACK_STRENGTH = register("trident_spin_attack_strength", null, null); //todo
public static final DataComponent<Unit> DAMAGE_PROTECTION = register("damage_protection", null); //todo
public static final DataComponent<Unit> DAMAGE_IMMUNITY = register("damage_immunity", null); //todo
public static final DataComponent<Unit> DAMAGE = register("damage", null); //todo
public static final DataComponent<Unit> SMASH_DAMAGE_PER_FALLEN_BLOCK = register("smash_damage_per_fallen_block", null); //todo
public static final DataComponent<Unit> KNOCKBACK = register("knockback", null); //todo
public static final DataComponent<Unit> ARMOR_EFFECTIVENESS = register("armor_effectiveness", null); //todo
public static final DataComponent<Unit> POST_ATTACK = register("post_attack", null); //todo
public static final DataComponent<Unit> HIT_BLOCK = register("hit_block", null); //todo
public static final DataComponent<Unit> ITEM_DAMAGE = register("item_damage", null); //todo
public static final DataComponent<Unit> ATTRIBUTES = register("attributes", null); //todo
public static final DataComponent<Unit> EQUIPMENT_DROPS = register("equipment_drops", null); //todo
public static final DataComponent<Unit> LOCATION_CHANGED = register("location_changed", null); //todo
public static final DataComponent<Unit> TICK = register("tick", null); //todo
public static final DataComponent<Unit> AMMO_USE = register("ammo_use", null); //todo
public static final DataComponent<Unit> PROJECTILE_PIERCING = register("projectile_piercing", null); //todo
public static final DataComponent<Unit> PROJECTILE_SPAWNED = register("projectile_spawned", null); //todo
public static final DataComponent<Unit> PROJECTILE_SPREAD = register("projectile_spread", null); //todo
public static final DataComponent<Unit> PROJECTILE_COUNT = register("projectile_count", null); //todo
public static final DataComponent<Unit> TRIDENT_RETURN_ACCELERATION = register("trident_return_acceleration", null); //todo
public static final DataComponent<Unit> FISHING_TIME_REDUCTION = register("fishing_time_reduction", null); //todo
public static final DataComponent<Unit> FISHING_LUCK_BONUS = register("fishing_luck_bonus", null); //todo
public static final DataComponent<Unit> BLOCK_EXPERIENCE = register("block_experience", null); //todo
public static final DataComponent<Unit> MOB_EXPERIENCE = register("mob_experience", null); //todo
public static final DataComponent<Unit> REPAIR_WITH_XP = register("repair_with_xp", null); //todo
public static final DataComponent<Unit> CROSSBOW_CHARGE_TIME = register("crossbow_charge_time", null); //todo
public static final DataComponent<Unit> CROSSBOW_CHARGING_SOUNDS = register("crossbow_charging_sounds", null); //todo
public static final DataComponent<Unit> TRIDENT_SOUND = register("trident_sound", null); //todo
public static final DataComponent<Unit> PREVENT_EQUIPMENT_DROP = register("prevent_equipment_drop", null); //todo
public static final DataComponent<Unit> PREVENT_ARMOR_CHANGE = register("prevent_armor_change", null); //todo
public static final DataComponent<Unit> TRIDENT_SPIN_ATTACK_STRENGTH = register("trident_spin_attack_strength", null); //todo
private static final BinaryTagSerializer<DataComponent<?>> COMPONENT_NBT_TYPE = BinaryTagSerializer.STRING.map(EnchantmentEffectComponent::fromNamespaceId, DataComponent::name);
public static final BinaryTagSerializer<DataComponentMap> 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 <T> DataComponent<T> register(@NotNull String name, @Nullable NetworkBuffer.Type<T> network, @Nullable BinaryTagSerializer<T> nbt) {
DataComponent<T> impl = DataComponent.createHeadless(NAMESPACES.size(), NamespaceID.from(name), network, nbt);
static <T> DataComponent<T> register(@NotNull String name, @Nullable BinaryTagSerializer<T> nbt) {
DataComponent<T> impl = DataComponent.createHeadless(NAMESPACES.size(), NamespaceID.from(name), null, nbt);
NAMESPACES.put(impl.name(), impl);
IDS.set(impl.id(), impl);
return impl;

View File

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

View File

@ -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<T extends ProtocolObject> implements DynamicRegi
@Override
public @NotNull DynamicRegistry.Key<T> 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());

View File

@ -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 <T> The type of protocol object represented by this set.
*/
interface Set<T extends ProtocolObject> {
}
@Contract(pure = true)
@NotNull NamespaceID namespace();