diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 960369de7..ff9ed8d25 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -655,12 +655,12 @@ public final class EntityDefinitions { .type(EntityType.PLAYER) .height(1.8f).width(0.6f) .offset(1.62f) + .addTranslator(null) // Player main hand + .addTranslator(MetadataTypes.BYTE, PlayerEntity::setSkinVisibility) .addTranslator(MetadataTypes.FLOAT, PlayerEntity::setAbsorptionHearts) .addTranslator(null) // Player score - .addTranslator(MetadataTypes.BYTE, PlayerEntity::setSkinVisibility) - .addTranslator(null) // Player main hand - .addTranslator(MetadataTypes.COMPOUND_TAG, PlayerEntity::setLeftParrot) - .addTranslator(MetadataTypes.COMPOUND_TAG, PlayerEntity::setRightParrot) + .addTranslator(MetadataTypes.OPTIONAL_UNSIGNED_INT, PlayerEntity::setLeftParrot) + .addTranslator(MetadataTypes.OPTIONAL_UNSIGNED_INT, PlayerEntity::setRightParrot) .build(); EntityDefinition mobEntityBase = EntityDefinition.inherited(MobEntity::new, livingEntityBase) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index a8ca770aa..4081c18dd 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -64,6 +64,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.OptionalInt; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -316,11 +317,11 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, ~entityMetadata.getPrimitiveValue() & 0xff); } - public void setLeftParrot(EntityMetadata entityMetadata) { + public void setLeftParrot(EntityMetadata entityMetadata) { setParrot(entityMetadata.getValue(), true); } - public void setRightParrot(EntityMetadata entityMetadata) { + public void setRightParrot(EntityMetadata entityMetadata) { setParrot(entityMetadata.getValue(), false); } @@ -328,17 +329,17 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { * Sets the parrot occupying the shoulder. Bedrock Edition requires a full entity whereas Java Edition just * spawns it from the NBT data provided */ - protected void setParrot(NbtMap tag, boolean isLeft) { - if (tag != null && !tag.isEmpty()) { + protected void setParrot(OptionalInt variant, boolean isLeft) { // TODO test this as of 1.21.9 + if (variant.isPresent()) { if ((isLeft && leftParrot != null) || (!isLeft && rightParrot != null)) { // No need to update a parrot's data when it already exists return; } - // The parrot is a separate entity in Bedrock, but part of the player entity in Java //TODO is a UUID provided in NBT? + // The parrot is a separate entity in Bedrock, but part of the player entity in Java ParrotEntity parrot = new ParrotEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(), null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw()); parrot.spawnEntity(); - parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, (Integer) tag.get("Variant")); + parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, variant.getAsInt()); // Different position whether the parrot is left or right float offset = isLeft ? 0.4f : -0.4f; parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_OFFSET, Vector3f.from(offset, -0.22, -0.1)); diff --git a/core/src/main/java/org/geysermc/geyser/item/hashing/DataComponentHashers.java b/core/src/main/java/org/geysermc/geyser/item/hashing/DataComponentHashers.java index b3343c9bb..40d8628c5 100644 --- a/core/src/main/java/org/geysermc/geyser/item/hashing/DataComponentHashers.java +++ b/core/src/main/java/org/geysermc/geyser/item/hashing/DataComponentHashers.java @@ -213,9 +213,9 @@ public class DataComponentHashers { register(DataComponentTypes.TRIM, RegistryHasher.ARMOR_TRIM); register(DataComponentTypes.DEBUG_STICK_STATE, MinecraftHasher.NBT_MAP); - register(DataComponentTypes.ENTITY_DATA, MinecraftHasher.NBT_MAP); + // register(DataComponentTypes.ENTITY_DATA, MinecraftHasher.NBT_MAP); TODO 1.21.9 register(DataComponentTypes.BUCKET_ENTITY_DATA, MinecraftHasher.NBT_MAP); - register(DataComponentTypes.BLOCK_ENTITY_DATA, MinecraftHasher.NBT_MAP); + // register(DataComponentTypes.BLOCK_ENTITY_DATA, MinecraftHasher.NBT_MAP); TODO 1.21.9 register(DataComponentTypes.INSTRUMENT, RegistryHasher.INSTRUMENT_COMPONENT); register(DataComponentTypes.PROVIDES_TRIM_MATERIAL, RegistryHasher.PROVIDES_TRIM_MATERIAL); @@ -235,7 +235,7 @@ public class DataComponentHashers { .optional("flight_duration", MinecraftHasher.BYTE, fireworks -> (byte) fireworks.getFlightDuration(), (byte) 0) .optionalList("explosions", RegistryHasher.FIREWORK_EXPLOSION, Fireworks::getExplosions)); - register(DataComponentTypes.PROFILE, MinecraftHasher.GAME_PROFILE); + // register(DataComponentTypes.PROFILE, MinecraftHasher.GAME_PROFILE); TODO 1.21.9 register(DataComponentTypes.NOTE_BLOCK_SOUND, MinecraftHasher.KEY); register(DataComponentTypes.BANNER_PATTERNS, RegistryHasher.BANNER_PATTERN_LAYER.list()); register(DataComponentTypes.BASE_COLOR, MinecraftHasher.DYE_COLOR); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java index 1ead9f2ad..be26cf47f 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/PlayerHeadItem.java @@ -49,7 +49,7 @@ public class PlayerHeadItem extends BlockItem { // Use the correct color, determined by the rarity of the item char rarity = Rarity.fromId(components.getOrDefault(DataComponentTypes.RARITY, Rarity.COMMON.ordinal())).getColor(); - GameProfile profile = components.get(DataComponentTypes.PROFILE); + /*GameProfile profile = components.get(DataComponentTypes.PROFILE); if (profile != null) { String name = profile.getName(); if (name != null) { @@ -62,6 +62,6 @@ public class PlayerHeadItem extends BlockItem { builder.setCustomName(ChatColor.RESET + ChatColor.ESCAPE + rarity + MinecraftLocale.getLocaleString("block.minecraft.player_head", session.locale())); } - } + }*/ // TODO 1.21.9 } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java b/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java index d41d160f8..e8645f856 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/type/SkullBlock.java @@ -36,6 +36,8 @@ import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.TypedEntityData; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import java.util.Collections; import java.util.UUID; @@ -74,12 +76,11 @@ public class SkullBlock extends Block { GeyserItemStack itemStack = GeyserItemStack.of(pickItem(state).getId(), 1); // This is a universal block entity behavior, but hardcode how it works for now. NbtMapBuilder builder = NbtMap.builder() - .putString("id", "minecraft:skull") .putInt("x", position.getX()) .putInt("y", position.getY()) .putInt("z", position.getZ()); DataComponents components = itemStack.getOrCreateComponents(); - components.put(DataComponentTypes.BLOCK_ENTITY_DATA, builder.build()); + components.put(DataComponentTypes.BLOCK_ENTITY_DATA, new TypedEntityData<>(BlockEntityType.SKULL, builder.build())); UUID uuid = skull.getUuid(); String texturesProperty = skull.getTexturesProperty(); @@ -87,7 +88,7 @@ public class SkullBlock extends Block { if (texturesProperty != null) { profile.setProperties(Collections.singletonList(new GameProfile.Property("textures", texturesProperty))); } - components.put(DataComponentTypes.PROFILE, profile); + // components.put(DataComponentTypes.PROFILE, profile); TODO 1.21.9 return itemStack.getItemStack(); } diff --git a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java index 0b08dd512..30053461e 100644 --- a/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/GameProtocol.java @@ -36,6 +36,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v843.Bedrock_v843; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.geysermc.geyser.api.util.MinecraftVersion; import org.geysermc.geyser.impl.MinecraftVersionImpl; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec; import org.geysermc.mcprotocollib.protocol.codec.PacketCodec; @@ -137,7 +138,9 @@ public final class GameProtocol { /* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */ - // There doesn't seem to be anything here at the moment... + public static boolean is1_21_100(GeyserSession session) { + return session.protocolVersion() == Bedrock_v827.CODEC.getProtocolVersion(); + } /** * Gets the supported Minecraft: Java Edition version names. diff --git a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java index d575ad5b2..73db9e243 100644 --- a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java @@ -30,6 +30,7 @@ import org.cloudburstmc.math.vector.Vector2f; import org.cloudburstmc.protocol.bedrock.BedrockDisconnectReasons; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.cloudburstmc.protocol.bedrock.codec.compat.BedrockCompat; +import org.cloudburstmc.protocol.bedrock.data.ExperimentData; import org.cloudburstmc.protocol.bedrock.data.PacketCompressionAlgorithm; import org.cloudburstmc.protocol.bedrock.data.ResourcePackType; import org.cloudburstmc.protocol.bedrock.netty.codec.compression.CompressionStrategy; @@ -288,7 +289,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { stackPacket.setGameVersion(session.getClientData().getGameVersion()); stackPacket.getResourcePacks().addAll(this.resourcePackLoadEvent.orderedPacks()); - // TODO support copper drop on .100 + if (GameProtocol.is1_21_100(session)) { + // Support copper age drop features (or some of them) in 1.21.100 + stackPacket.getExperiments().add(new ExperimentData("y_2025_drop_3", true)); + } session.sendUpstreamPacket(stackPacket); } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 47325d51d..2bbbe0673 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -59,6 +59,7 @@ import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.block.type.FlowerPotBlock; import org.geysermc.geyser.registry.BlockRegistries; +import org.geysermc.geyser.registry.populator.conversion.Conversion827_819; import org.geysermc.geyser.registry.populator.conversion.Conversion843_827; import org.geysermc.geyser.registry.type.BlockMappings; import org.geysermc.geyser.registry.type.GeyserBedrockBlock; @@ -119,10 +120,10 @@ public final class BlockRegistryPopulator { private static void registerBedrockBlocks() { var blockMappers = ImmutableMap., Remapper>builder() - .put(ObjectIntPair.of("1_21_90", Bedrock_v818.CODEC.getProtocolVersion()), Conversion843_827::remapBlock) - .put(ObjectIntPair.of("1_21_90", Bedrock_v819.CODEC.getProtocolVersion()), Conversion843_827::remapBlock) + .put(ObjectIntPair.of("1_21_90", Bedrock_v818.CODEC.getProtocolVersion()), Conversion827_819::remapBlock) + .put(ObjectIntPair.of("1_21_90", Bedrock_v819.CODEC.getProtocolVersion()), Conversion827_819::remapBlock) .put(ObjectIntPair.of("1_21_100", Bedrock_v827.CODEC.getProtocolVersion()), Conversion843_827::remapBlock) - .put(ObjectIntPair.of("1_21_110", Bedrock_v843.CODEC.getProtocolVersion()), tag -> tag) // TODO conversion? + .put(ObjectIntPair.of("1_21_110", Bedrock_v843.CODEC.getProtocolVersion()), tag -> tag) .build(); // We can keep this strong as nothing should be garbage collected diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index f59f1f266..5bde81d6e 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -86,6 +86,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -119,11 +120,82 @@ public class ItemRegistryPopulator { } public static void populate() { - List paletteVersions = new ArrayList<>(6); - paletteVersions.add(new PaletteVersion("1_21_90", Bedrock_v818.CODEC.getProtocolVersion(), Map.of(Items.MUSIC_DISC_LAVA_CHICKEN, Items.MUSIC_DISC_CHIRP), Conversion843_827::remapItem)); - paletteVersions.add(new PaletteVersion("1_21_93", Bedrock_v819.CODEC.getProtocolVersion(), Conversion843_827::remapItem)); - paletteVersions.add(new PaletteVersion("1_21_100", Bedrock_v827.CODEC.getProtocolVersion(), Conversion843_827::remapItem)); - paletteVersions.add(new PaletteVersion("1_21_110", Bedrock_v843.CODEC.getProtocolVersion())); // TODO fallback + Map eightTwoSevenFallbacks = new HashMap<>(); + eightTwoSevenFallbacks.put(Items.ACACIA_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.BAMBOO_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.BIRCH_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.CHERRY_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.CRIMSON_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.DARK_OAK_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.JUNGLE_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.MANGROVE_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.OAK_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.PALE_OAK_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.SPRUCE_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.WARPED_SHELF, Items.CHISELED_BOOKSHELF); + eightTwoSevenFallbacks.put(Items.COPPER_BARS, Items.IRON_BARS); + eightTwoSevenFallbacks.put(Items.EXPOSED_COPPER_BARS, Items.IRON_BARS); + eightTwoSevenFallbacks.put(Items.WEATHERED_COPPER_BARS, Items.IRON_BARS); + eightTwoSevenFallbacks.put(Items.OXIDIZED_COPPER_BARS, Items.IRON_BARS); + eightTwoSevenFallbacks.put(Items.WAXED_COPPER_BARS, Items.IRON_BARS); + eightTwoSevenFallbacks.put(Items.WAXED_EXPOSED_COPPER_BARS, Items.IRON_BARS); + eightTwoSevenFallbacks.put(Items.WAXED_WEATHERED_COPPER_BARS, Items.IRON_BARS); + eightTwoSevenFallbacks.put(Items.WAXED_OXIDIZED_COPPER_BARS, Items.IRON_BARS); + eightTwoSevenFallbacks.put(Items.COPPER_GOLEM_STATUE, Items.ARMOR_STAND); + eightTwoSevenFallbacks.put(Items.EXPOSED_COPPER_GOLEM_STATUE, Items.ARMOR_STAND); + eightTwoSevenFallbacks.put(Items.WEATHERED_COPPER_GOLEM_STATUE, Items.ARMOR_STAND); + eightTwoSevenFallbacks.put(Items.OXIDIZED_COPPER_GOLEM_STATUE, Items.ARMOR_STAND); + eightTwoSevenFallbacks.put(Items.WAXED_COPPER_GOLEM_STATUE, Items.ARMOR_STAND); + eightTwoSevenFallbacks.put(Items.WAXED_EXPOSED_COPPER_GOLEM_STATUE, Items.ARMOR_STAND); + eightTwoSevenFallbacks.put(Items.WAXED_WEATHERED_COPPER_GOLEM_STATUE, Items.ARMOR_STAND); + eightTwoSevenFallbacks.put(Items.WAXED_OXIDIZED_COPPER_GOLEM_STATUE, Items.ARMOR_STAND); + eightTwoSevenFallbacks.put(Items.COPPER_LANTERN, Items.LANTERN); + eightTwoSevenFallbacks.put(Items.EXPOSED_COPPER_LANTERN, Items.LANTERN); + eightTwoSevenFallbacks.put(Items.WEATHERED_COPPER_LANTERN, Items.LANTERN); + eightTwoSevenFallbacks.put(Items.OXIDIZED_COPPER_LANTERN, Items.LANTERN); + eightTwoSevenFallbacks.put(Items.WAXED_COPPER_LANTERN, Items.LANTERN); + eightTwoSevenFallbacks.put(Items.WAXED_EXPOSED_COPPER_LANTERN, Items.LANTERN); + eightTwoSevenFallbacks.put(Items.WAXED_WEATHERED_COPPER_LANTERN, Items.LANTERN); + eightTwoSevenFallbacks.put(Items.WAXED_OXIDIZED_COPPER_LANTERN, Items.LANTERN); + eightTwoSevenFallbacks.put(Items.EXPOSED_LIGHTNING_ROD, Items.LIGHTNING_ROD); + eightTwoSevenFallbacks.put(Items.WEATHERED_LIGHTNING_ROD, Items.LIGHTNING_ROD); + eightTwoSevenFallbacks.put(Items.OXIDIZED_LIGHTNING_ROD, Items.LIGHTNING_ROD); + eightTwoSevenFallbacks.put(Items.WAXED_LIGHTNING_ROD, Items.LIGHTNING_ROD); + eightTwoSevenFallbacks.put(Items.WAXED_EXPOSED_LIGHTNING_ROD, Items.LIGHTNING_ROD); + eightTwoSevenFallbacks.put(Items.WAXED_WEATHERED_LIGHTNING_ROD, Items.LIGHTNING_ROD); + eightTwoSevenFallbacks.put(Items.WAXED_OXIDIZED_LIGHTNING_ROD, Items.LIGHTNING_ROD); + eightTwoSevenFallbacks.put(Items.COPPER_TORCH, Items.TORCH); + eightTwoSevenFallbacks.put(Items.COPPER_HORSE_ARMOR, Items.LEATHER_HORSE_ARMOR); + + Map eightOneNineFallbacks = new HashMap<>(eightTwoSevenFallbacks); + eightOneNineFallbacks.put(Items.COPPER_CHEST, Items.CHEST); + eightOneNineFallbacks.put(Items.EXPOSED_COPPER_CHEST, Items.CHEST); + eightOneNineFallbacks.put(Items.WEATHERED_COPPER_CHEST, Items.CHEST); + eightOneNineFallbacks.put(Items.OXIDIZED_COPPER_CHEST, Items.CHEST); + eightOneNineFallbacks.put(Items.WAXED_COPPER_CHEST, Items.CHEST); + eightOneNineFallbacks.put(Items.WAXED_EXPOSED_COPPER_CHEST, Items.CHEST); + eightOneNineFallbacks.put(Items.WAXED_WEATHERED_COPPER_CHEST, Items.CHEST); + eightOneNineFallbacks.put(Items.WAXED_OXIDIZED_COPPER_CHEST, Items.CHEST); + eightOneNineFallbacks.put(Items.COPPER_HELMET, Items.LEATHER_HELMET); + eightOneNineFallbacks.put(Items.COPPER_CHESTPLATE, Items.LEATHER_CHESTPLATE); + eightOneNineFallbacks.put(Items.COPPER_LEGGINGS, Items.LEATHER_LEGGINGS); + eightOneNineFallbacks.put(Items.COPPER_BOOTS, Items.LEATHER_BOOTS); + eightOneNineFallbacks.put(Items.COPPER_NUGGET, Items.IRON_NUGGET); + eightOneNineFallbacks.put(Items.COPPER_SWORD, Items.STONE_SWORD); + eightOneNineFallbacks.put(Items.COPPER_PICKAXE, Items.STONE_PICKAXE); + eightOneNineFallbacks.put(Items.COPPER_SHOVEL, Items.STONE_SHOVEL); + eightOneNineFallbacks.put(Items.COPPER_AXE, Items.STONE_AXE); + eightOneNineFallbacks.put(Items.COPPER_HOE, Items.STONE_HOE); + eightOneNineFallbacks.put(Items.COPPER_GOLEM_SPAWN_EGG, Items.IRON_GOLEM_SPAWN_EGG); + + Map eightOneEightFallbacks = new HashMap<>(eightOneNineFallbacks); + eightOneEightFallbacks.put(Items.MUSIC_DISC_LAVA_CHICKEN, Items.MUSIC_DISC_CHIRP); + + List paletteVersions = new ArrayList<>(4); + paletteVersions.add(new PaletteVersion("1_21_90", Bedrock_v818.CODEC.getProtocolVersion(), eightOneEightFallbacks, Conversion843_827::remapItem)); + paletteVersions.add(new PaletteVersion("1_21_93", Bedrock_v819.CODEC.getProtocolVersion(), eightOneNineFallbacks, Conversion843_827::remapItem)); + paletteVersions.add(new PaletteVersion("1_21_100", Bedrock_v827.CODEC.getProtocolVersion(), eightTwoSevenFallbacks, Conversion843_827::remapItem)); + paletteVersions.add(new PaletteVersion("1_21_110", Bedrock_v843.CODEC.getProtocolVersion())); GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap(); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/conversion/Conversion827_819.java b/core/src/main/java/org/geysermc/geyser/registry/populator/conversion/Conversion827_819.java new file mode 100644 index 000000000..41ee456fe --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/conversion/Conversion827_819.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.registry.populator.conversion; + +import org.cloudburstmc.nbt.NbtMap; + +public class Conversion827_819 { + + public static NbtMap remapBlock(NbtMap nbtMap) { + nbtMap = Conversion843_827.remapBlock(nbtMap); + + final String name = nbtMap.getString("name"); + if (name.endsWith("copper_chest")) { + return ConversionHelper.withName(nbtMap, "chest"); + } + + return nbtMap; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/conversion/Conversion843_827.java b/core/src/main/java/org/geysermc/geyser/registry/populator/conversion/Conversion843_827.java index b2fa25f75..d3ef9a608 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/conversion/Conversion843_827.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/conversion/Conversion843_827.java @@ -35,21 +35,30 @@ public class Conversion843_827 { public static NbtMap remapBlock(NbtMap nbtMap) { final String name = nbtMap.getString("name"); - if (name.equals("minecraft:iron_chain")) { + if (name.equals("minecraft:iron_chain") || name.endsWith("copper_chain")) { return ConversionHelper.withName(nbtMap, "chain"); - } else if (name.equals("minecraft:lightning_rod")) { + } else if (name.endsWith("lightning_rod")) { NbtMapBuilder statesWithoutPoweredBit = nbtMap.getCompound("states").toBuilder(); statesWithoutPoweredBit.remove("powered_bit"); return nbtMap.toBuilder() + .putString("name", "minecraft:lightning_rod") .putCompound("states", statesWithoutPoweredBit.build()) .build(); + } else if (name.endsWith("_shelf") || name.endsWith("copper_golem_statue")) { + return ConversionHelper.withoutStates("unknown"); + } else if (name.equals("minecraft:copper_torch")) { + return ConversionHelper.withName(nbtMap, "torch"); + } else if (name.endsWith("copper_bars")) { + return ConversionHelper.withName(nbtMap, "iron_bars"); + } else if (name.endsWith("copper_lantern")) { + return ConversionHelper.withName(nbtMap, "lantern"); } return nbtMap; } public static GeyserMappingItem remapItem(Item item, GeyserMappingItem mapping) { - if (item == Items.IRON_CHAIN) { + if (item == Items.IRON_CHAIN || item.javaIdentifier().endsWith("copper_chain")) { return mapping.withBedrockIdentifier("minecraft:chain"); } return mapping; diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 7079cf10b..32c1610b3 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -155,6 +155,7 @@ import org.geysermc.geyser.item.type.BlockItem; import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.level.physics.CollisionManager; +import org.geysermc.geyser.network.GameProtocol; import org.geysermc.geyser.network.netty.LocalSession; import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.type.BlockMappings; @@ -1794,7 +1795,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { startGamePacket.getExperiments().add(new ExperimentData("upcoming_creator_features", true)); // Needed for certain molang queries used in blocks and items startGamePacket.getExperiments().add(new ExperimentData("experimental_molang_features", true)); - // TODO Enable 2025 Content Drop 3 features on .100 + + // Enable 2025 Content Drop 3 features on 1.21.100 + if (GameProtocol.is1_21_100(this)) { + startGamePacket.getExperiments().add(new ExperimentData("y_2025_drop_3", true)); + } startGamePacket.setVanillaVersion("*"); startGamePacket.setInventoriesServerAuthoritative(true); diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java index 08f73a381..a1843c0fe 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/SkullCache.java @@ -47,6 +47,7 @@ import org.geysermc.geyser.skin.SkinManager; import java.io.IOException; import java.util.*; +// TODO 1.21.9 public class SkullCache { private final int maxVisibleSkulls; private final boolean cullingEnabled; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index baf53487d..1b1bb1465 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -331,7 +331,7 @@ public abstract class InventoryTranslator { GeyserItemStack javaItem = inventory.getItem(sourceSlot); if (javaItem.asItem() == Items.PLAYER_HEAD && javaItem.hasNonBaseComponents()) { - FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponent(DataComponentTypes.PROFILE)); + //FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponent(DataComponentTypes.PROFILE)); TODO 1.21.9 } } else if (sourceSlot == 5) { // we are probably removing the head, so restore the original skin diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 15109a574..5617b3c5e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -111,7 +111,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator= 1 && slot <= 44) { @@ -287,7 +287,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { - GameProfile profile = stack.getComponent(DataComponentTypes.PROFILE); + /*GameProfile profile = stack.getComponent(DataComponentTypes.PROFILE); if (livingEntity instanceof PlayerEntity && stack.asItem() == Items.PLAYER_HEAD && profile != null) { FakeHeadProvider.setHead(session, (PlayerEntity) livingEntity, profile); } else { FakeHeadProvider.restoreOriginalSkin(session, livingEntity); - } + }*/ // TODO 1.21.9 livingEntity.setHelmet(stack); armorUpdated = true; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5cc8603f8..09dd38615 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ protocol-common = "3.0.0.Beta8-NO-ADVENTURE-SNAPSHOT" protocol-codec = "3.0.0.Beta8-NO-ADVENTURE-SNAPSHOT" raknet = "1.0.0.CR3-20250811.214335-20" minecraftauth = "4.1.1" -mcprotocollib = "1.21.7-20250915.111046-6" +mcprotocollib = "1.21.9-SNAPSHOT" adventure = "4.24.0" adventure-platform = "4.3.0" junit = "5.9.2" diff --git a/settings.gradle.kts b/settings.gradle.kts index 9aaf6ba59..dd631ab8a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -20,7 +20,7 @@ include(":ap") include(":api") include(":bungeecord") include(":fabric") -include(":neoforge") +//include(":neoforge") TODO 1.21.9 include(":mod") include(":spigot") include(":standalone") @@ -32,7 +32,7 @@ include(":core") // Specify project dirs project(":bungeecord").projectDir = file("bootstrap/bungeecord") project(":fabric").projectDir = file("bootstrap/mod/fabric") -project(":neoforge").projectDir = file("bootstrap/mod/neoforge") +//project(":neoforge").projectDir = file("bootstrap/mod/neoforge") TODO 1.21.9 project(":mod").projectDir = file("bootstrap/mod") project(":spigot").projectDir = file("bootstrap/spigot") project(":standalone").projectDir = file("bootstrap/standalone")