1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-19 14:59:27 +00:00

Write hashers for new data components, still needs testing

This commit is contained in:
Eclipse
2025-12-11 11:23:25 +00:00
parent e1f2c2ca68
commit 0082293c73
2 changed files with 59 additions and 2 deletions

View File

@@ -52,6 +52,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
import org.geysermc.mcprotocollib.protocol.data.game.item.HashedStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.AttackRange;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BlockStateProperties;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BlocksAttacks;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Consumable;
@@ -68,15 +69,19 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.IntComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.KineticWeapon;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectDetails;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectInstance;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PiercingWeapon;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.SwingAnimation;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ToolData;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.TooltipDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.TypedEntityData;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unit;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.UseCooldown;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.UseEffects;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Weapon;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent;
@@ -101,8 +106,14 @@ public class DataComponentHashers {
registerInt(DataComponentTypes.MAX_DAMAGE);
registerInt(DataComponentTypes.DAMAGE);
registerUnit(DataComponentTypes.UNBREAKABLE);
registerMap(DataComponentTypes.USE_EFFECTS, builder -> builder
.optional("can_sprint", MinecraftHasher.BOOL, UseEffects::canSprint, false)
.optional("interact_vibrations", MinecraftHasher.BOOL, UseEffects::interactVibrations, true)
.optional("speed_multiplier", MinecraftHasher.FLOAT, UseEffects::speedMultiplier, 0.2F)); // TODO test 1.21.11
register(DataComponentTypes.CUSTOM_NAME, ComponentHasher.COMPONENT);
register(DataComponentTypes.MINIMUM_ATTACK_CHARGE, MinecraftHasher.FLOAT);
register(DataComponentTypes.DAMAGE_TYPE, RegistryHasher.eitherHolderHasher(JavaRegistries.DAMAGE_TYPE));
register(DataComponentTypes.ITEM_NAME, ComponentHasher.COMPONENT);
register(DataComponentTypes.ITEM_MODEL, MinecraftHasher.KEY);
register(DataComponentTypes.LORE, ComponentHasher.COMPONENT.list());
@@ -154,6 +165,21 @@ public class DataComponentHashers {
registerMap(DataComponentTypes.WEAPON, builder -> builder
.optional("item_damage_per_attack", MinecraftHasher.INT, Weapon::itemDamagePerAttack, 1)
.optional("disable_blocking_for_seconds", MinecraftHasher.FLOAT, Weapon::disableBlockingForSeconds, 0.0F));
registerMap(DataComponentTypes.PIERCING_WEAPON, builder -> builder
.optional("deals_knockback", MinecraftHasher.BOOL, PiercingWeapon::dealsKnockback, true)
.optional("dismounts", MinecraftHasher.BOOL, PiercingWeapon::dealsKnockback, false)
.optionalNullable("sound", RegistryHasher.SOUND_EVENT, PiercingWeapon::sound)
.optionalNullable("hit_sound", RegistryHasher.SOUND_EVENT, PiercingWeapon::hitSound)); // TODO test 1.21.11
registerMap(DataComponentTypes.ATTACK_RANGE, builder -> builder
.optional("min_reach", MinecraftHasher.FLOAT, AttackRange::minRange, 0.0F)
.optional("max_reach", MinecraftHasher.FLOAT, AttackRange::maxRange, 3.0F)
.optional("min_creative_reach", MinecraftHasher.FLOAT, AttackRange::minCreativeRange, 0.0F)
.optional("max_creative_reach", MinecraftHasher.FLOAT, AttackRange::maxCreativeRange, 5.0F)
.optional("hitbox_margin", MinecraftHasher.FLOAT, AttackRange::hitboxMargin, 0.3F)
.optional("mob_factor", MinecraftHasher.FLOAT, AttackRange::mobFactor, 1.0F)); // TODO test 1.21.11
registerMap(DataComponentTypes.SWING_ANIMATION, builder -> builder
.optional("type", RegistryHasher.SWING_ANIMATION_TYPE, SwingAnimation::type, SwingAnimation.Type.WHACK)
.optional("duration", MinecraftHasher.INT, SwingAnimation::duration, 6)); // TODO test 1.21.11
registerMap(DataComponentTypes.ENCHANTABLE, builder -> builder
.accept("value", MinecraftHasher.INT, Function.identity()));
registerMap(DataComponentTypes.EQUIPPABLE, builder -> builder
@@ -184,6 +210,16 @@ public class DataComponentHashers {
.optionalNullable("bypassed_by", MinecraftHasher.TAG, BlocksAttacks::bypassedBy)
.optionalNullable("block_sound", RegistryHasher.SOUND_EVENT, BlocksAttacks::blockSound)
.optionalNullable("disabled_sound", RegistryHasher.SOUND_EVENT, BlocksAttacks::disableSound)); // TODO needs tests
registerMap(DataComponentTypes.KINETIC_WEAPON, builder -> builder
.optional("contact_cooldown_ticks", MinecraftHasher.INT, KineticWeapon::contactCooldownTicks, 10)
.optional("delay_ticks", MinecraftHasher.INT, KineticWeapon::contactCooldownTicks, 0)
.optionalNullable("dismount_conditions", RegistryHasher.KINETIC_WEAPON_CONDITION, KineticWeapon::dismountConditions)
.optionalNullable("knockback_conditions", RegistryHasher.KINETIC_WEAPON_CONDITION, KineticWeapon::knockbackConditions)
.optionalNullable("damage_conditions", RegistryHasher.KINETIC_WEAPON_CONDITION, KineticWeapon::damageConditions)
.optional("forward_movement", MinecraftHasher.FLOAT, KineticWeapon::forwardMovement, 0.0F)
.optional("damage_multiplier", MinecraftHasher.FLOAT, KineticWeapon::damageMultiplier, 1.0F)
.optionalNullable("sound", RegistryHasher.SOUND_EVENT, KineticWeapon::sound)
.optionalNullable("hit_sound", RegistryHasher.SOUND_EVENT, KineticWeapon::hitSound)); // TODO test 1.21.11
register(DataComponentTypes.STORED_ENCHANTMENTS, RegistryHasher.ITEM_ENCHANTMENTS);
registerInt(DataComponentTypes.DYED_COLOR);
@@ -267,8 +303,8 @@ public class DataComponentHashers {
register(DataComponentTypes.RABBIT_VARIANT, RegistryHasher.RABBIT_VARIANT);
register(DataComponentTypes.PIG_VARIANT, RegistryHasher.PIG_VARIANT);
register(DataComponentTypes.COW_VARIANT, RegistryHasher.COW_VARIANT);
register(DataComponentTypes.CHICKEN_VARIANT, MinecraftHasher.KEY
.registryCast((session, holder) -> holder.getOrCompute(id -> JavaRegistries.CHICKEN_VARIANT.key(session, id)))); // Why, Mojang?
register(DataComponentTypes.CHICKEN_VARIANT, RegistryHasher.eitherHolderHasher(JavaRegistries.CHICKEN_VARIANT));
register(DataComponentTypes.ZOMBIE_NAUTILUS_VARIANT, RegistryHasher.eitherHolderHasher(JavaRegistries.ZOMBIE_NAUTILUS_VARIANT)); // TODO test 1.21.11
register(DataComponentTypes.FROG_VARIANT, RegistryHasher.FROG_VARIANT);
register(DataComponentTypes.HORSE_VARIANT, RegistryHasher.HORSE_VARIANT);
register(DataComponentTypes.PAINTING_VARIANT, RegistryHasher.PAINTING_VARIANT.cast(Holder::id)); // This can and will throw when a direct holder was received, which is still possible due to a bug in 1.21.6.

View File

@@ -67,10 +67,12 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.InstrumentCo
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.JukeboxPlayable;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.KineticWeapon;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectDetails;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectInstance;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ProvidesTrimMaterial;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.SuspiciousStewEffect;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.SwingAnimation;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ToolData;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unit;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@@ -328,6 +330,13 @@ public interface RegistryHasher<DirectType> extends MinecraftHasher<Integer> {
.accept("base", FLOAT, BlocksAttacks.ItemDamageFunction::base)
.accept("factor", FLOAT, BlocksAttacks.ItemDamageFunction::factor));
MinecraftHasher<KineticWeapon.Condition> KINETIC_WEAPON_CONDITION = MinecraftHasher.mapBuilder(builder -> builder
.accept("max_duration_ticks", MinecraftHasher.INT, KineticWeapon.Condition::maxDurationTicks)
.optional("min_speed", MinecraftHasher.FLOAT, KineticWeapon.Condition::minSpeed, 0.0F)
.optional("min_relative_speed", MinecraftHasher.FLOAT, KineticWeapon.Condition::minRelativeSpeed, 0.0F));
MinecraftHasher<SwingAnimation.Type> SWING_ANIMATION_TYPE = MinecraftHasher.fromEnum();
MinecraftHasher<ProvidesTrimMaterial> PROVIDES_TRIM_MATERIAL = MinecraftHasher.either(TRIM_MATERIAL.holder(), ProvidesTrimMaterial::materialHolder, KEY, ProvidesTrimMaterial::materialLocation);
MinecraftHasher<ArmorTrim> ARMOR_TRIM = MinecraftHasher.mapBuilder(builder -> builder
@@ -455,6 +464,18 @@ public interface RegistryHasher<DirectType> extends MinecraftHasher<Integer> {
return hasher::hash;
}
/**
* Creates a hasher that hashes a {@code Holder<Key>}, also known as an {@code EitherHolder} in Mojmap.
*
* <p>Please note that a {@code Holder<Key>} is only a valid representation of an {@code EitherHolder} in MCPL if the stream codec of the {@code EitherHolder} does not support directly encoding unregistered values.</p>
*
* @param registry the registry the {@code Holder} is for.
* @return a hasher that hashes a {@code Holder<Key>} for the given registry.
*/
static MinecraftHasher<Holder<Key>> eitherHolderHasher(JavaRegistryKey<?> registry) {
return MinecraftHasher.KEY.registryCast((registries, holder) -> holder.getOrCompute(id -> registry.key(registries, id)));
}
class RegistryHasherWithDirectHasher<DirectType> implements RegistryHasher<DirectType> {
private final MinecraftHasher<Integer> id;
private final MinecraftHasher<Holder<DirectType>> holderHasher;