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

Initial 1.21.5 changes

This commit is contained in:
onebeastchris
2025-03-20 16:26:10 +01:00
parent 61fea614f3
commit acb858f0ab
35 changed files with 9197 additions and 6154 deletions

View File

@@ -70,4 +70,5 @@ repositories {
content { includeGroupByRegex("com\\.github\\..*") } content { includeGroupByRegex("com\\.github\\..*") }
} }
mavenLocal()
} }

View File

@@ -473,8 +473,9 @@ public final class EntityDefinitions {
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:xp_bottle") .identifier("minecraft:xp_bottle")
.build(); .build();
// TODO 1.21.5 lingering potion
POTION = EntityDefinition.inherited(ThrownPotionEntity::new, throwableItemBase) POTION = EntityDefinition.inherited(ThrownPotionEntity::new, throwableItemBase)
.type(EntityType.POTION) .type(EntityType.SPLASH_POTION)
.heightAndWidth(0.25f) .heightAndWidth(0.25f)
.identifier("minecraft:splash_potion") .identifier("minecraft:splash_potion")
.build(); .build();
@@ -960,6 +961,7 @@ public final class EntityDefinitions {
.type(EntityType.CHICKEN) .type(EntityType.CHICKEN)
.height(0.7f).width(0.4f) .height(0.7f).width(0.4f)
.properties(VanillaEntityProperties.CLIMATE_VARIANT) .properties(VanillaEntityProperties.CLIMATE_VARIANT)
.addTranslator(MetadataTypes.CHICKEN_VARIANT, ChickenEntity::setVariant)
.build(); .build();
COW = EntityDefinition.inherited(CowEntity::new, ageableEntityBase) COW = EntityDefinition.inherited(CowEntity::new, ageableEntityBase)
.type(EntityType.COW) .type(EntityType.COW)
@@ -1016,8 +1018,8 @@ public final class EntityDefinitions {
.type(EntityType.PIG) .type(EntityType.PIG)
.heightAndWidth(0.9f) .heightAndWidth(0.9f)
.properties(VanillaEntityProperties.CLIMATE_VARIANT) .properties(VanillaEntityProperties.CLIMATE_VARIANT)
.addTranslator(MetadataTypes.BOOLEAN, (pigEntity, entityMetadata) -> pigEntity.setFlag(EntityFlag.SADDLED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
.addTranslator(MetadataTypes.INT, PigEntity::setBoost) .addTranslator(MetadataTypes.INT, PigEntity::setBoost)
.addTranslator(MetadataTypes.PIG_VARIANT, PigEntity::setVariant)
.build(); .build();
POLAR_BEAR = EntityDefinition.inherited(PolarBearEntity::new, ageableEntityBase) POLAR_BEAR = EntityDefinition.inherited(PolarBearEntity::new, ageableEntityBase)
.type(EntityType.POLAR_BEAR) .type(EntityType.POLAR_BEAR)
@@ -1045,7 +1047,6 @@ public final class EntityDefinitions {
.height(1.7f).width(0.9f) .height(1.7f).width(0.9f)
.addTranslator(MetadataTypes.INT, StriderEntity::setBoost) .addTranslator(MetadataTypes.INT, StriderEntity::setBoost)
.addTranslator(MetadataTypes.BOOLEAN, StriderEntity::setCold) .addTranslator(MetadataTypes.BOOLEAN, StriderEntity::setCold)
.addTranslator(MetadataTypes.BOOLEAN, StriderEntity::setSaddled)
.build(); .build();
TURTLE = EntityDefinition.inherited(TurtleEntity::new, ageableEntityBase) TURTLE = EntityDefinition.inherited(TurtleEntity::new, ageableEntityBase)
.type(EntityType.TURTLE) .type(EntityType.TURTLE)
@@ -1144,7 +1145,7 @@ public final class EntityDefinitions {
EntityDefinition<TameableEntity> tameableEntityBase = EntityDefinition.<TameableEntity>inherited(null, ageableEntityBase) // No factory, is abstract EntityDefinition<TameableEntity> tameableEntityBase = EntityDefinition.<TameableEntity>inherited(null, ageableEntityBase) // No factory, is abstract
.addTranslator(MetadataTypes.BYTE, TameableEntity::setTameableFlags) .addTranslator(MetadataTypes.BYTE, TameableEntity::setTameableFlags)
.addTranslator(MetadataTypes.OPTIONAL_UUID, TameableEntity::setOwner) .addTranslator(MetadataTypes.OPTIONAL_LIVING_ENTITY_REFERENCE, TameableEntity::setOwner)
.build(); .build();
CAT = EntityDefinition.inherited(CatEntity::new, tameableEntityBase) CAT = EntityDefinition.inherited(CatEntity::new, tameableEntityBase)
.type(EntityType.CAT) .type(EntityType.CAT)

View File

@@ -35,7 +35,7 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.MathUtils; import org.geysermc.geyser.util.MathUtils;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ColorParticleData;
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
import java.util.UUID; import java.util.UUID;
@@ -72,7 +72,7 @@ public class AreaEffectCloudEntity extends Entity {
Registries.PARTICLES.map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type -> Registries.PARTICLES.map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type ->
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE, type)); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE, type));
if (particle.getData() instanceof EntityEffectParticleData effectParticleData) { if (particle.getData() instanceof ColorParticleData effectParticleData) {
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, effectParticleData.getColor()); dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, effectParticleData.getColor());
} }
} }

View File

@@ -62,7 +62,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.Object
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; 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.DataComponentTypes;
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ColorParticleData;
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
@@ -80,6 +80,7 @@ public class LivingEntity extends Entity {
protected ItemData leggings = ItemData.AIR; protected ItemData leggings = ItemData.AIR;
protected ItemData boots = ItemData.AIR; protected ItemData boots = ItemData.AIR;
protected ItemData body = ItemData.AIR; protected ItemData body = ItemData.AIR;
protected ItemData saddle = ItemData.AIR;
protected ItemData hand = ItemData.AIR; protected ItemData hand = ItemData.AIR;
protected ItemData offhand = ItemData.AIR; protected ItemData offhand = ItemData.AIR;
@@ -118,10 +119,6 @@ public class LivingEntity extends Entity {
this.chestplate = ItemTranslator.translateToBedrock(session, stack); this.chestplate = ItemTranslator.translateToBedrock(session, stack);
} }
public void setBody(ItemStack stack) {
this.body = ItemTranslator.translateToBedrock(session, stack);
}
public void setLeggings(ItemStack stack) { public void setLeggings(ItemStack stack) {
this.leggings = ItemTranslator.translateToBedrock(session, stack); this.leggings = ItemTranslator.translateToBedrock(session, stack);
} }
@@ -130,6 +127,15 @@ public class LivingEntity extends Entity {
this.boots = ItemTranslator.translateToBedrock(session, stack); this.boots = ItemTranslator.translateToBedrock(session, stack);
} }
public void setBody(ItemStack stack) {
this.body = ItemTranslator.translateToBedrock(session, stack);
}
public void setSaddle(ItemStack stack) {
this.saddle = ItemTranslator.translateToBedrock(session, stack);
updateSaddled(stack.getId() == Items.SADDLE.javaId());
}
public void setHand(ItemStack stack) { public void setHand(ItemStack stack) {
this.hand = ItemTranslator.translateToBedrock(session, stack); this.hand = ItemTranslator.translateToBedrock(session, stack);
} }
@@ -138,6 +144,18 @@ public class LivingEntity extends Entity {
this.offhand = ItemTranslator.translateToBedrock(session, stack); this.offhand = ItemTranslator.translateToBedrock(session, stack);
} }
protected void updateSaddled(boolean saddled) {
setFlag(EntityFlag.SADDLED, saddled);
updateBedrockMetadata();
// Update the interactive tag, if necessary
// TODO 1.21.5 retest
Entity mouseoverEntity = session.getMouseoverEntity();
if (mouseoverEntity != null && mouseoverEntity.getEntityId() == entityId) {
mouseoverEntity.updateInteractiveTag();
}
}
public void switchHands() { public void switchHands() {
ItemData offhand = this.offhand; ItemData offhand = this.offhand;
this.offhand = this.hand; this.offhand = this.hand;
@@ -202,7 +220,7 @@ public class LivingEntity extends Entity {
continue; continue;
} }
int color = ((EntityEffectParticleData) particle.getData()).getColor(); int color = ((ColorParticleData) particle.getData()).getColor();
r += ((color >> 16) & 0xFF) / 255f; r += ((color >> 16) & 0xFF) / 255f;
g += ((color >> 8) & 0xFF) / 255f; g += ((color >> 8) & 0xFF) / 255f;
b += ((color) & 0xFF) / 255f; b += ((color) & 0xFF) / 255f;

View File

@@ -120,7 +120,7 @@ public class ThrowableEntity extends Entity implements Tickable {
protected float getGravity() { protected float getGravity() {
if (getFlag(EntityFlag.HAS_GRAVITY)) { if (getFlag(EntityFlag.HAS_GRAVITY)) {
switch (definition.entityType()) { switch (definition.entityType()) {
case POTION: case LINGERING_POTION, SPLASH_POTION:
return 0.05f; return 0.05f;
case EXPERIENCE_BOTTLE: case EXPERIENCE_BOTTLE:
return 0.07f; return 0.07f;
@@ -146,7 +146,7 @@ public class ThrowableEntity extends Entity implements Tickable {
return 0.8f; return 0.8f;
} else { } else {
switch (definition.entityType()) { switch (definition.entityType()) {
case POTION: case LINGERING_POTION, SPLASH_POTION:
case EXPERIENCE_BOTTLE: case EXPERIENCE_BOTTLE:
case SNOWBALL: case SNOWBALL:
case EGG: case EGG:

View File

@@ -48,6 +48,10 @@ import org.geysermc.geyser.session.cache.tags.Tag;
import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.EntityUtils;
import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag; import org.geysermc.geyser.util.InteractiveTag;
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.PigVariant;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
@@ -155,4 +159,8 @@ public class PigEntity extends AnimalEntity implements Tickable, ClientVehicle {
public boolean isClientControlled() { public boolean isClientControlled() {
return getPlayerPassenger() == session.getPlayerEntity() && session.getPlayerInventory().isHolding(Items.CARROT_ON_A_STICK); return getPlayerPassenger() == session.getPlayerEntity() && session.getPlayerInventory().isHolding(Items.CARROT_ON_A_STICK);
} }
public void setVariant(EntityMetadata<Holder<PigVariant>,? extends MetadataType<Holder<PigVariant>>> holderEntityMetadata) {
// TODO
}
} }

View File

@@ -69,10 +69,6 @@ public class StriderEntity extends AnimalEntity implements Tickable, ClientVehic
isCold = entityMetadata.getPrimitiveValue(); isCold = entityMetadata.getPrimitiveValue();
} }
public void setSaddled(BooleanEntityMetadata entityMetadata) {
setFlag(EntityFlag.SADDLED, entityMetadata.getPrimitiveValue());
}
@Override @Override
public void updateBedrockMetadata() { public void updateBedrockMetadata() {
// Make sure they are not shaking when riding another entity // Make sure they are not shaking when riding another entity

View File

@@ -79,12 +79,19 @@ public class AbstractHorseEntity extends AnimalEntity {
session.sendUpstreamPacket(attributesPacket); session.sendUpstreamPacket(attributesPacket);
} }
@Override
public void updateSaddled(boolean saddled) {
// Shows the jump meter
setFlag(EntityFlag.CAN_POWER_JUMP, saddled);
super.updateSaddled(saddled);
}
// TODO 1.21.5 saddled flag doesnt exist anymore
public void setHorseFlags(ByteEntityMetadata entityMetadata) { public void setHorseFlags(ByteEntityMetadata entityMetadata) {
byte xd = entityMetadata.getPrimitiveValue(); byte xd = entityMetadata.getPrimitiveValue();
boolean tamed = (xd & 0x02) == 0x02; boolean tamed = (xd & 0x02) == 0x02;
boolean saddled = (xd & 0x04) == 0x04; boolean saddled = (xd & 0x04) == 0x04;
setFlag(EntityFlag.TAMED, tamed); setFlag(EntityFlag.TAMED, tamed);
setFlag(EntityFlag.SADDLED, saddled);
setFlag(EntityFlag.EATING, (xd & 0x10) == 0x10); setFlag(EntityFlag.EATING, (xd & 0x10) == 0x10);
setFlag(EntityFlag.STANDING, (xd & 0x20) == 0x20); setFlag(EntityFlag.STANDING, (xd & 0x20) == 0x20);
@@ -114,9 +121,6 @@ public class AbstractHorseEntity extends AnimalEntity {
// Set container type if tamed // Set container type if tamed
dirtyMetadata.put(EntityDataTypes.CONTAINER_TYPE, tamed ? (byte) ContainerType.HORSE.getId() : (byte) 0); dirtyMetadata.put(EntityDataTypes.CONTAINER_TYPE, tamed ? (byte) ContainerType.HORSE.getId() : (byte) 0);
// Shows the jump meter
setFlag(EntityFlag.CAN_POWER_JUMP, saddled);
} }
@Override @Override

View File

@@ -34,11 +34,13 @@ import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade; import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundMerchantOffersPacket;
import java.util.List;
public class MerchantContainer extends Container { public class MerchantContainer extends Container {
@Getter @Setter @Getter @Setter
private Entity villager; private Entity villager;
@Setter @Setter
private VillagerTrade[] villagerTrades; private List<VillagerTrade> villagerTrades;
@Getter @Setter @Getter @Setter
private ClientboundMerchantOffersPacket pendingOffersPacket; private ClientboundMerchantOffersPacket pendingOffersPacket;
@Getter @Setter @Getter @Setter
@@ -49,9 +51,9 @@ public class MerchantContainer extends Container {
} }
public void onTradeSelected(GeyserSession session, int slot) { public void onTradeSelected(GeyserSession session, int slot) {
if (villagerTrades != null && slot >= 0 && slot < villagerTrades.length) { if (villagerTrades != null && slot >= 0 && slot < villagerTrades.size()) {
VillagerTrade trade = villagerTrades[slot]; VillagerTrade trade = villagerTrades.get(slot);
setItem(2, GeyserItemStack.from(trade.getOutput()), session); setItem(2, GeyserItemStack.from(trade.getResult()), session);
tradeExperience += trade.getXp(); tradeExperience += trade.getXp();
villager.getDirtyMetadata().put(EntityDataTypes.TRADE_EXPERIENCE, tradeExperience); villager.getDirtyMetadata().put(EntityDataTypes.TRADE_EXPERIENCE, tradeExperience);

View File

@@ -34,8 +34,7 @@ import org.geysermc.geyser.session.cache.registry.RegistryEntryContext;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.geyser.util.SoundUtils; import org.geysermc.geyser.util.SoundUtils;
import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.item.component.InstrumentComponent;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument;
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound;
import java.util.Locale; import java.util.Locale;
@@ -90,34 +89,35 @@ public interface GeyserInstrument {
return -1; return -1;
} }
static GeyserInstrument fromHolder(GeyserSession session, Holder<Instrument> holder) { // TODO 1.21.5
if (holder.isId()) { static GeyserInstrument fromComponent(GeyserSession session, InstrumentComponent component) {
return session.getRegistryCache().instruments().byId(holder.id()); if (component.instrumentHolder().isId()) {
return session.getRegistryCache().instruments().byId(component.instrumentHolder().id());
} }
Instrument custom = holder.custom(); InstrumentComponent.Instrument custom = component.instrumentHolder().custom();
return new Wrapper(custom, session.locale()); return new Wrapper(custom, session.locale());
} }
record Wrapper(Instrument instrument, String locale) implements GeyserInstrument { record Wrapper(InstrumentComponent.Instrument instrument, String locale) implements GeyserInstrument {
@Override @Override
public String soundEvent() { public String soundEvent() {
return instrument.getSoundEvent().getName(); return instrument.soundEvent().getName();
} }
@Override @Override
public float range() { public float range() {
return instrument.getRange(); return instrument.range();
} }
@Override @Override
public String description() { public String description() {
return MessageTranslator.convertMessageForTooltip(instrument.getDescription(), locale); return MessageTranslator.convertMessageForTooltip(instrument.description(), locale);
} }
@Override @Override
public BedrockInstrument bedrockInstrument() { public BedrockInstrument bedrockInstrument() {
if (instrument.getSoundEvent() instanceof BuiltinSound) { if (instrument.soundEvent() instanceof BuiltinSound) {
return BedrockInstrument.getByJavaIdentifier(MinecraftKey.key(instrument.getSoundEvent().getName())); return BedrockInstrument.getByJavaIdentifier(MinecraftKey.key(instrument.soundEvent().getName()));
} }
// Probably custom // Probably custom
return null; return null;

View File

@@ -270,9 +270,13 @@ public final class Items {
public static final Item COBWEB = register(new BlockItem(builder(), Blocks.COBWEB)); public static final Item COBWEB = register(new BlockItem(builder(), Blocks.COBWEB));
public static final Item SHORT_GRASS = register(new BlockItem(builder(), Blocks.SHORT_GRASS)); public static final Item SHORT_GRASS = register(new BlockItem(builder(), Blocks.SHORT_GRASS));
public static final Item FERN = register(new BlockItem(builder(), Blocks.FERN)); public static final Item FERN = register(new BlockItem(builder(), Blocks.FERN));
public static final Item BUSH = register(new BlockItem(builder(), Blocks.BUSH));
public static final Item AZALEA = register(new BlockItem(builder(), Blocks.AZALEA)); public static final Item AZALEA = register(new BlockItem(builder(), Blocks.AZALEA));
public static final Item FLOWERING_AZALEA = register(new BlockItem(builder(), Blocks.FLOWERING_AZALEA)); public static final Item FLOWERING_AZALEA = register(new BlockItem(builder(), Blocks.FLOWERING_AZALEA));
public static final Item DEAD_BUSH = register(new BlockItem(builder(), Blocks.DEAD_BUSH)); public static final Item DEAD_BUSH = register(new BlockItem(builder(), Blocks.DEAD_BUSH));
public static final Item FIREFLY_BUSH = register(new BlockItem(builder(), Blocks.FIREFLY_BUSH));
public static final Item SHORT_DRY_GRASS = register(new BlockItem(builder(), Blocks.SHORT_DRY_GRASS));
public static final Item TALL_DRY_GRASS = register(new BlockItem(builder(), Blocks.TALL_DRY_GRASS));
public static final Item SEAGRASS = register(new BlockItem(builder(), Blocks.SEAGRASS)); public static final Item SEAGRASS = register(new BlockItem(builder(), Blocks.SEAGRASS));
public static final Item SEA_PICKLE = register(new BlockItem(builder(), Blocks.SEA_PICKLE)); public static final Item SEA_PICKLE = register(new BlockItem(builder(), Blocks.SEA_PICKLE));
public static final Item WHITE_WOOL = register(new BlockItem(builder(), Blocks.WHITE_WOOL)); public static final Item WHITE_WOOL = register(new BlockItem(builder(), Blocks.WHITE_WOOL));
@@ -321,6 +325,8 @@ public final class Items {
public static final Item SUGAR_CANE = register(new BlockItem(builder(), Blocks.SUGAR_CANE)); public static final Item SUGAR_CANE = register(new BlockItem(builder(), Blocks.SUGAR_CANE));
public static final Item KELP = register(new BlockItem(builder(), Blocks.KELP)); public static final Item KELP = register(new BlockItem(builder(), Blocks.KELP));
public static final Item PINK_PETALS = register(new BlockItem(builder(), Blocks.PINK_PETALS)); public static final Item PINK_PETALS = register(new BlockItem(builder(), Blocks.PINK_PETALS));
public static final Item WILDFLOWERS = register(new BlockItem(builder(), Blocks.WILDFLOWERS));
public static final Item LEAF_LITTER = register(new BlockItem(builder(), Blocks.LEAF_LITTER));
public static final Item MOSS_CARPET = register(new BlockItem(builder(), Blocks.MOSS_CARPET)); public static final Item MOSS_CARPET = register(new BlockItem(builder(), Blocks.MOSS_CARPET));
public static final Item MOSS_BLOCK = register(new BlockItem(builder(), Blocks.MOSS_BLOCK)); public static final Item MOSS_BLOCK = register(new BlockItem(builder(), Blocks.MOSS_BLOCK));
public static final Item PALE_MOSS_CARPET = register(new BlockItem(builder(), Blocks.PALE_MOSS_CARPET)); public static final Item PALE_MOSS_CARPET = register(new BlockItem(builder(), Blocks.PALE_MOSS_CARPET));
@@ -389,6 +395,7 @@ public final class Items {
public static final Item ICE = register(new BlockItem(builder(), Blocks.ICE)); public static final Item ICE = register(new BlockItem(builder(), Blocks.ICE));
public static final Item SNOW_BLOCK = register(new BlockItem(builder(), Blocks.SNOW_BLOCK)); public static final Item SNOW_BLOCK = register(new BlockItem(builder(), Blocks.SNOW_BLOCK));
public static final Item CACTUS = register(new BlockItem(builder(), Blocks.CACTUS)); public static final Item CACTUS = register(new BlockItem(builder(), Blocks.CACTUS));
public static final Item CACTUS_FLOWER = register(new BlockItem(builder(), Blocks.CACTUS_FLOWER));
public static final Item CLAY = register(new BlockItem(builder(), Blocks.CLAY)); public static final Item CLAY = register(new BlockItem(builder(), Blocks.CLAY));
public static final Item JUKEBOX = register(new BlockItem(builder(), Blocks.JUKEBOX)); public static final Item JUKEBOX = register(new BlockItem(builder(), Blocks.JUKEBOX));
public static final Item OAK_FENCE = register(new BlockItem(builder(), Blocks.OAK_FENCE)); public static final Item OAK_FENCE = register(new BlockItem(builder(), Blocks.OAK_FENCE));
@@ -891,6 +898,8 @@ public final class Items {
public static final Item BAMBOO_CHEST_RAFT = register(new BoatItem("bamboo_chest_raft", builder())); public static final Item BAMBOO_CHEST_RAFT = register(new BoatItem("bamboo_chest_raft", builder()));
public static final Item STRUCTURE_BLOCK = register(new BlockItem(builder(), Blocks.STRUCTURE_BLOCK)); public static final Item STRUCTURE_BLOCK = register(new BlockItem(builder(), Blocks.STRUCTURE_BLOCK));
public static final Item JIGSAW = register(new BlockItem(builder(), Blocks.JIGSAW)); public static final Item JIGSAW = register(new BlockItem(builder(), Blocks.JIGSAW));
public static final Item TEST_BLOCK = register(new BlockItem(builder(), Blocks.TEST_BLOCK));
public static final Item TEST_INSTANCE_BLOCK = register(new BlockItem(builder(), Blocks.TEST_INSTANCE_BLOCK));
public static final Item TURTLE_HELMET = register(new ArmorItem("turtle_helmet", builder())); public static final Item TURTLE_HELMET = register(new ArmorItem("turtle_helmet", builder()));
public static final Item TURTLE_SCUTE = register(new Item("turtle_scute", builder())); public static final Item TURTLE_SCUTE = register(new Item("turtle_scute", builder()));
public static final Item ARMADILLO_SCUTE = register(new Item("armadillo_scute", builder())); public static final Item ARMADILLO_SCUTE = register(new Item("armadillo_scute", builder()));
@@ -1027,6 +1036,8 @@ public final class Items {
public static final Item BOOK = register(new Item("book", builder())); public static final Item BOOK = register(new Item("book", builder()));
public static final Item SLIME_BALL = register(new Item("slime_ball", builder())); public static final Item SLIME_BALL = register(new Item("slime_ball", builder()));
public static final Item EGG = register(new Item("egg", builder())); public static final Item EGG = register(new Item("egg", builder()));
public static final Item BLUE_EGG = register(new Item("blue_egg", builder()));
public static final Item BROWN_EGG = register(new Item("brown_egg", builder()));
public static final Item COMPASS = register(new CompassItem("compass", builder())); public static final Item COMPASS = register(new CompassItem("compass", builder()));
public static final Item RECOVERY_COMPASS = register(new Item("recovery_compass", builder())); public static final Item RECOVERY_COMPASS = register(new Item("recovery_compass", builder()));
public static final Item BUNDLE = register(new Item("bundle", builder())); public static final Item BUNDLE = register(new Item("bundle", builder()));
@@ -1120,7 +1131,7 @@ public final class Items {
public static final Item BLAZE_POWDER = register(new Item("blaze_powder", builder())); public static final Item BLAZE_POWDER = register(new Item("blaze_powder", builder()));
public static final Item MAGMA_CREAM = register(new Item("magma_cream", builder())); public static final Item MAGMA_CREAM = register(new Item("magma_cream", builder()));
public static final Item BREWING_STAND = register(new BlockItem(builder(), Blocks.BREWING_STAND)); public static final Item BREWING_STAND = register(new BlockItem(builder(), Blocks.BREWING_STAND));
public static final Item CAULDRON = register(new BlockItem(builder(), Blocks.CAULDRON, Blocks.POWDER_SNOW_CAULDRON, Blocks.LAVA_CAULDRON, Blocks.WATER_CAULDRON)); public static final Item CAULDRON = register(new BlockItem(builder(), Blocks.CAULDRON, Blocks.POWDER_SNOW_CAULDRON, Blocks.WATER_CAULDRON, Blocks.LAVA_CAULDRON));
public static final Item ENDER_EYE = register(new Item("ender_eye", builder())); public static final Item ENDER_EYE = register(new Item("ender_eye", builder()));
public static final Item GLISTERING_MELON_SLICE = register(new Item("glistering_melon_slice", builder())); public static final Item GLISTERING_MELON_SLICE = register(new Item("glistering_melon_slice", builder()));
public static final Item ARMADILLO_SPAWN_EGG = register(new SpawnEggItem("armadillo_spawn_egg", builder())); public static final Item ARMADILLO_SPAWN_EGG = register(new SpawnEggItem("armadillo_spawn_egg", builder()));
@@ -1210,7 +1221,7 @@ public final class Items {
public static final Item WRITABLE_BOOK = register(new WritableBookItem("writable_book", builder())); public static final Item WRITABLE_BOOK = register(new WritableBookItem("writable_book", builder()));
public static final Item WRITTEN_BOOK = register(new WrittenBookItem("written_book", builder())); public static final Item WRITTEN_BOOK = register(new WrittenBookItem("written_book", builder()));
public static final Item BREEZE_ROD = register(new Item("breeze_rod", builder())); public static final Item BREEZE_ROD = register(new Item("breeze_rod", builder()));
public static final Item MACE = register(new Item("mace", builder())); public static final Item MACE = register(new Item("mace", builder().attackDamage(6.0)));
public static final Item ITEM_FRAME = register(new Item("item_frame", builder())); public static final Item ITEM_FRAME = register(new Item("item_frame", builder()));
public static final Item GLOW_ITEM_FRAME = register(new Item("glow_item_frame", builder())); public static final Item GLOW_ITEM_FRAME = register(new Item("glow_item_frame", builder()));
public static final Item FLOWER_POT = register(new BlockItem(builder(), Blocks.FLOWER_POT)); public static final Item FLOWER_POT = register(new BlockItem(builder(), Blocks.FLOWER_POT));

View File

@@ -46,7 +46,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer; import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; 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.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -226,7 +225,7 @@ public class BannerItem extends BlockItem {
} }
components.put(DataComponentTypes.BANNER_PATTERNS, patternLayers); components.put(DataComponentTypes.BANNER_PATTERNS, patternLayers);
components.put(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); // TODO 1.21.5 hide components???
components.put(DataComponentTypes.ITEM_NAME, Component components.put(DataComponentTypes.ITEM_NAME, Component
.translatable("block.minecraft.ominous_banner") .translatable("block.minecraft.ominous_banner")
.style(Style.style(TextColor.color(16755200))) .style(Style.style(TextColor.color(16755200)))

View File

@@ -36,7 +36,7 @@ import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; 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.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument; import org.geysermc.mcprotocollib.protocol.data.game.item.component.InstrumentComponent;
public class GoatHornItem extends Item { public class GoatHornItem extends Item {
public GoatHornItem(String javaIdentifier, Builder builder) { public GoatHornItem(String javaIdentifier, Builder builder) {
@@ -50,9 +50,9 @@ public class GoatHornItem extends Item {
return builder; return builder;
} }
Holder<Instrument> holder = components.get(DataComponentTypes.INSTRUMENT); InstrumentComponent instrumentComponent = components.get(DataComponentTypes.INSTRUMENT);
if (holder != null) { if (instrumentComponent != null) {
GeyserInstrument instrument = GeyserInstrument.fromHolder(session, holder); GeyserInstrument instrument = GeyserInstrument.fromComponent(session, instrumentComponent);
int bedrockId = instrument.bedrockId(); int bedrockId = instrument.bedrockId();
if (bedrockId >= 0) { if (bedrockId >= 0) {
builder.damage(bedrockId); builder.damage(bedrockId);
@@ -66,10 +66,10 @@ public class GoatHornItem extends Item {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder); super.translateComponentsToBedrock(session, components, builder);
Holder<Instrument> holder = components.get(DataComponentTypes.INSTRUMENT); InstrumentComponent component = components.get(DataComponentTypes.INSTRUMENT);
if (holder != null && components.get(DataComponentTypes.HIDE_TOOLTIP) == null // TODO 1.21.5 hiding????
&& components.get(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) == null) { if (component != null) {
GeyserInstrument instrument = GeyserInstrument.fromHolder(session, holder); GeyserInstrument instrument = GeyserInstrument.fromComponent(session, component);
if (instrument.bedrockInstrument() == null) { if (instrument.bedrockInstrument() == null) {
builder.getOrCreateLore().add(instrument.description()); builder.getOrCreateLore().add(instrument.description());
} }
@@ -82,7 +82,7 @@ public class GoatHornItem extends Item {
int damage = itemData.getDamage(); int damage = itemData.getDamage();
// This could cause an issue since -1 is returned for non-vanilla goat horns // This could cause an issue since -1 is returned for non-vanilla goat horns
itemStack.getOrCreateComponents().put(DataComponentTypes.INSTRUMENT, Holder.ofId(GeyserInstrument.bedrockIdToJava(session, damage))); itemStack.getOrCreateComponents().put(DataComponentTypes.INSTRUMENT, new InstrumentComponent(Holder.ofId(GeyserInstrument.bedrockIdToJava(session, damage)), null));
return itemStack; return itemStack;
} }

View File

@@ -46,12 +46,10 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.MinecraftKey; import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; 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.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DyedItemColor;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
import org.jetbrains.annotations.UnmodifiableView; import org.jetbrains.annotations.UnmodifiableView;
@@ -159,12 +157,13 @@ public class Item {
*/ */
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) { public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
List<Component> loreComponents = components.get(DataComponentTypes.LORE); List<Component> loreComponents = components.get(DataComponentTypes.LORE);
if (loreComponents != null && components.get(DataComponentTypes.HIDE_TOOLTIP) == null) { // TODO 1.21.5
List<String> lore = builder.getOrCreateLore(); // if (loreComponents != null && components.get(DataComponentTypes.HIDE_TOOLTIP) == null) {
for (Component loreComponent : loreComponents) { // List<String> lore = builder.getOrCreateLore();
lore.add(MessageTranslator.convertMessage(loreComponent, session.locale())); // for (Component loreComponent : loreComponents) {
} // lore.add(MessageTranslator.convertMessage(loreComponent, session.locale()));
} // }
// }
Integer damage = components.get(DataComponentTypes.DAMAGE); Integer damage = components.get(DataComponentTypes.DAMAGE);
if (damage != null) { if (damage != null) {
@@ -266,10 +265,11 @@ public class Item {
} }
protected final void translateDyedColor(DataComponents components, BedrockItemBuilder builder) { protected final void translateDyedColor(DataComponents components, BedrockItemBuilder builder) {
DyedItemColor dyedItemColor = components.get(DataComponentTypes.DYED_COLOR); // TODO 1.21.5
if (dyedItemColor != null) { // DyedItemColor dyedItemColor = components.get(DataComponentTypes.DYED_COLOR);
builder.putInt("customColor", dyedItemColor.getRgb()); // if (dyedItemColor != null) {
} // builder.putInt("customColor", dyedItemColor.getRgb());
// }
} }
/** /**

View File

@@ -325,6 +325,9 @@ public final class Blocks {
public static final Block SHORT_GRASS = register(new Block("short_grass", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SHORT_GRASS = register(new Block("short_grass", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block FERN = register(new Block("fern", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block FERN = register(new Block("fern", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block DEAD_BUSH = register(new Block("dead_bush", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block DEAD_BUSH = register(new Block("dead_bush", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block BUSH = register(new Block("bush", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block SHORT_DRY_GRASS = register(new Block("short_dry_grass", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block TALL_DRY_GRASS = register(new Block("tall_dry_grass", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block SEAGRASS = register(new Block("seagrass", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SEAGRASS = register(new Block("seagrass", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.SEAGRASS) public static final Block TALL_SEAGRASS = register(new Block("tall_seagrass", builder().pushReaction(PistonBehavior.DESTROY).pickItem(() -> Items.SEAGRASS)
.enumState(DOUBLE_BLOCK_HALF))); .enumState(DOUBLE_BLOCK_HALF)));
@@ -399,8 +402,8 @@ public final class Blocks {
public static final Block SOUL_FIRE = register(new Block("soul_fire", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block SOUL_FIRE = register(new Block("soul_fire", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block SPAWNER = register(new SpawnerBlock("spawner", builder().setBlockEntity(BlockEntityType.MOB_SPAWNER).requiresCorrectToolForDrops().destroyTime(5.0f))); public static final Block SPAWNER = register(new SpawnerBlock("spawner", builder().setBlockEntity(BlockEntityType.MOB_SPAWNER).requiresCorrectToolForDrops().destroyTime(5.0f)));
public static final Block CREAKING_HEART = register(new Block("creaking_heart", builder().setBlockEntity(BlockEntityType.CREAKING_HEART).destroyTime(10.0f) public static final Block CREAKING_HEART = register(new Block("creaking_heart", builder().setBlockEntity(BlockEntityType.CREAKING_HEART).destroyTime(10.0f)
.booleanState(ACTIVE)
.enumState(AXIS, Axis.VALUES) .enumState(AXIS, Axis.VALUES)
.enumState(CREAKING_HEART_STATE)
.booleanState(NATURAL))); .booleanState(NATURAL)));
public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder().destroyTime(2.0f) public static final Block OAK_STAIRS = register(new Block("oak_stairs", builder().destroyTime(2.0f)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
@@ -630,7 +633,7 @@ public final class Blocks {
public static final Block REDSTONE_WALL_TORCH = register(new Block("redstone_wall_torch", builder().pushReaction(PistonBehavior.DESTROY) public static final Block REDSTONE_WALL_TORCH = register(new Block("redstone_wall_torch", builder().pushReaction(PistonBehavior.DESTROY)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(LIT))); .booleanState(LIT)));
public static final Block STONE_BUTTON = register(new ButtonBlock("stone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block STONE_BUTTON = register(new Block("stone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
@@ -640,6 +643,7 @@ public final class Blocks {
public static final Block SNOW_BLOCK = register(new Block("snow_block", builder().requiresCorrectToolForDrops().destroyTime(0.2f))); public static final Block SNOW_BLOCK = register(new Block("snow_block", builder().requiresCorrectToolForDrops().destroyTime(0.2f)));
public static final Block CACTUS = register(new Block("cactus", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY) public static final Block CACTUS = register(new Block("cactus", builder().destroyTime(0.4f).pushReaction(PistonBehavior.DESTROY)
.intState(AGE_15))); .intState(AGE_15)));
public static final Block CACTUS_FLOWER = register(new Block("cactus_flower", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block CLAY = register(new Block("clay", builder().destroyTime(0.6f))); public static final Block CLAY = register(new Block("clay", builder().destroyTime(0.6f)));
public static final Block SUGAR_CANE = register(new Block("sugar_cane", builder().pushReaction(PistonBehavior.DESTROY) public static final Block SUGAR_CANE = register(new Block("sugar_cane", builder().pushReaction(PistonBehavior.DESTROY)
.intState(AGE_15))); .intState(AGE_15)));
@@ -997,43 +1001,43 @@ public final class Blocks {
.intState(AGE_7))); .intState(AGE_7)));
public static final Block POTATOES = register(new Block("potatoes", builder().pushReaction(PistonBehavior.DESTROY) public static final Block POTATOES = register(new Block("potatoes", builder().pushReaction(PistonBehavior.DESTROY)
.intState(AGE_7))); .intState(AGE_7)));
public static final Block OAK_BUTTON = register(new ButtonBlock("oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block OAK_BUTTON = register(new Block("oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block SPRUCE_BUTTON = register(new ButtonBlock("spruce_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block SPRUCE_BUTTON = register(new Block("spruce_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block BIRCH_BUTTON = register(new ButtonBlock("birch_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block BIRCH_BUTTON = register(new Block("birch_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block JUNGLE_BUTTON = register(new ButtonBlock("jungle_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block JUNGLE_BUTTON = register(new Block("jungle_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block ACACIA_BUTTON = register(new ButtonBlock("acacia_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block ACACIA_BUTTON = register(new Block("acacia_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block CHERRY_BUTTON = register(new ButtonBlock("cherry_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block CHERRY_BUTTON = register(new Block("cherry_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block DARK_OAK_BUTTON = register(new ButtonBlock("dark_oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block DARK_OAK_BUTTON = register(new Block("dark_oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block PALE_OAK_BUTTON = register(new ButtonBlock("pale_oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block PALE_OAK_BUTTON = register(new Block("pale_oak_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block MANGROVE_BUTTON = register(new ButtonBlock("mangrove_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block MANGROVE_BUTTON = register(new Block("mangrove_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block BAMBOO_BUTTON = register(new ButtonBlock("bamboo_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block BAMBOO_BUTTON = register(new Block("bamboo_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
@@ -2232,11 +2236,11 @@ public final class Blocks {
.enumState(HALF) .enumState(HALF)
.enumState(STAIRS_SHAPE) .enumState(STAIRS_SHAPE)
.booleanState(WATERLOGGED))); .booleanState(WATERLOGGED)));
public static final Block CRIMSON_BUTTON = register(new ButtonBlock("crimson_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block CRIMSON_BUTTON = register(new Block("crimson_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block WARPED_BUTTON = register(new ButtonBlock("warped_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block WARPED_BUTTON = register(new Block("warped_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
@@ -2268,6 +2272,9 @@ public final class Blocks {
.enumState(STRUCTUREBLOCK_MODE))); .enumState(STRUCTUREBLOCK_MODE)));
public static final Block JIGSAW = register(new Block("jigsaw", builder().setBlockEntity(BlockEntityType.JIGSAW).requiresCorrectToolForDrops().destroyTime(-1.0f) public static final Block JIGSAW = register(new Block("jigsaw", builder().setBlockEntity(BlockEntityType.JIGSAW).requiresCorrectToolForDrops().destroyTime(-1.0f)
.enumState(ORIENTATION, FrontAndTop.VALUES))); .enumState(ORIENTATION, FrontAndTop.VALUES)));
public static final Block TEST_BLOCK = register(new Block("test_block", builder().setBlockEntity(BlockEntityType.TEST_BLOCK).destroyTime(-1.0f)
.enumState(TEST_BLOCK_MODE)));
public static final Block TEST_INSTANCE_BLOCK = register(new Block("test_instance_block", builder().setBlockEntity(BlockEntityType.TEST_INSTANCE_BLOCK).destroyTime(-1.0f)));
public static final Block COMPOSTER = register(new Block("composter", builder().destroyTime(0.6f) public static final Block COMPOSTER = register(new Block("composter", builder().destroyTime(0.6f)
.intState(LEVEL_COMPOSTER))); .intState(LEVEL_COMPOSTER)));
public static final Block TARGET = register(new Block("target", builder().destroyTime(0.5f) public static final Block TARGET = register(new Block("target", builder().destroyTime(0.5f)
@@ -2336,7 +2343,7 @@ public final class Blocks {
.booleanState(WATERLOGGED))); .booleanState(WATERLOGGED)));
public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block POLISHED_BLACKSTONE_PRESSURE_PLATE = register(new Block("polished_blackstone_pressure_plate", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.booleanState(POWERED))); .booleanState(POWERED)));
public static final Block POLISHED_BLACKSTONE_BUTTON = register(new ButtonBlock("polished_blackstone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY) public static final Block POLISHED_BLACKSTONE_BUTTON = register(new Block("polished_blackstone_button", builder().destroyTime(0.5f).pushReaction(PistonBehavior.DESTROY)
.enumState(ATTACH_FACE) .enumState(ATTACH_FACE)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.booleanState(POWERED))); .booleanState(POWERED)));
@@ -2790,6 +2797,12 @@ public final class Blocks {
public static final Block PINK_PETALS = register(new Block("pink_petals", builder().pushReaction(PistonBehavior.DESTROY) public static final Block PINK_PETALS = register(new Block("pink_petals", builder().pushReaction(PistonBehavior.DESTROY)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.intState(FLOWER_AMOUNT))); .intState(FLOWER_AMOUNT)));
public static final Block WILDFLOWERS = register(new Block("wildflowers", builder().pushReaction(PistonBehavior.DESTROY)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.intState(FLOWER_AMOUNT)));
public static final Block LEAF_LITTER = register(new Block("leaf_litter", builder().pushReaction(PistonBehavior.DESTROY)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
.intState(SEGMENT_AMOUNT)));
public static final Block MOSS_BLOCK = register(new Block("moss_block", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY))); public static final Block MOSS_BLOCK = register(new Block("moss_block", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY)));
public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY) public static final Block BIG_DRIPLEAF = register(new Block("big_dripleaf", builder().destroyTime(0.1f).pushReaction(PistonBehavior.DESTROY)
.enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) .enumState(HORIZONTAL_FACING, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST)
@@ -2921,6 +2934,7 @@ public final class Blocks {
public static final Block CLOSED_EYEBLOSSOM = register(new Block("closed_eyeblossom", builder().pushReaction(PistonBehavior.DESTROY))); public static final Block CLOSED_EYEBLOSSOM = register(new Block("closed_eyeblossom", builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block POTTED_OPEN_EYEBLOSSOM = register(new FlowerPotBlock("potted_open_eyeblossom", OPEN_EYEBLOSSOM, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_OPEN_EYEBLOSSOM = register(new FlowerPotBlock("potted_open_eyeblossom", OPEN_EYEBLOSSOM, builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block POTTED_CLOSED_EYEBLOSSOM = register(new FlowerPotBlock("potted_closed_eyeblossom", CLOSED_EYEBLOSSOM, builder().pushReaction(PistonBehavior.DESTROY))); public static final Block POTTED_CLOSED_EYEBLOSSOM = register(new FlowerPotBlock("potted_closed_eyeblossom", CLOSED_EYEBLOSSOM, builder().pushReaction(PistonBehavior.DESTROY)));
public static final Block FIREFLY_BUSH = register(new Block("firefly_bush", builder().pushReaction(PistonBehavior.DESTROY)));
private static <T extends Block> T register(T block) { private static <T extends Block> T register(T block) {
block.setJavaId(BlockRegistries.JAVA_BLOCKS.get().size()); block.setJavaId(BlockRegistries.JAVA_BLOCKS.get().size());

View File

@@ -29,7 +29,6 @@ import org.geysermc.geyser.level.physics.Axis;
import org.geysermc.geyser.level.physics.Direction; import org.geysermc.geyser.level.physics.Direction;
public final class Properties { public final class Properties {
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public static final BooleanProperty ATTACHED = BooleanProperty.create("attached"); public static final BooleanProperty ATTACHED = BooleanProperty.create("attached");
public static final BooleanProperty BERRIES = BooleanProperty.create("berries"); public static final BooleanProperty BERRIES = BooleanProperty.create("berries");
public static final BooleanProperty BLOOM = BooleanProperty.create("bloom"); public static final BooleanProperty BLOOM = BooleanProperty.create("bloom");
@@ -77,6 +76,7 @@ public final class Properties {
public static final EnumProperty<Direction> FACING_HOPPER = EnumProperty.create("facing", Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST); public static final EnumProperty<Direction> FACING_HOPPER = EnumProperty.create("facing", Direction.DOWN, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST);
public static final EnumProperty<Direction> HORIZONTAL_FACING = EnumProperty.create("facing", Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST); public static final EnumProperty<Direction> HORIZONTAL_FACING = EnumProperty.create("facing", Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST);
public static final IntegerProperty FLOWER_AMOUNT = IntegerProperty.create("flower_amount", 1, 4); public static final IntegerProperty FLOWER_AMOUNT = IntegerProperty.create("flower_amount", 1, 4);
public static final IntegerProperty SEGMENT_AMOUNT = IntegerProperty.create("segment_amount", 1, 4);
public static final EnumProperty<FrontAndTop> ORIENTATION = EnumProperty.create("orientation", FrontAndTop.VALUES); public static final EnumProperty<FrontAndTop> ORIENTATION = EnumProperty.create("orientation", FrontAndTop.VALUES);
public static final BasicEnumProperty ATTACH_FACE = BasicEnumProperty.create("face", "floor", "wall", "ceiling"); public static final BasicEnumProperty ATTACH_FACE = BasicEnumProperty.create("face", "floor", "wall", "ceiling");
public static final BasicEnumProperty BELL_ATTACHMENT = BasicEnumProperty.create("attachment", "floor", "ceiling", "single_wall", "double_wall"); public static final BasicEnumProperty BELL_ATTACHMENT = BasicEnumProperty.create("attachment", "floor", "ceiling", "single_wall", "double_wall");
@@ -145,5 +145,8 @@ public final class Properties {
public static final BooleanProperty CRAFTING = BooleanProperty.create("crafting"); public static final BooleanProperty CRAFTING = BooleanProperty.create("crafting");
public static final BasicEnumProperty TRIAL_SPAWNER_STATE = BasicEnumProperty.create("trial_spawner_state", "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown"); public static final BasicEnumProperty TRIAL_SPAWNER_STATE = BasicEnumProperty.create("trial_spawner_state", "inactive", "waiting_for_players", "active", "waiting_for_reward_ejection", "ejecting_reward", "cooldown");
public static final BasicEnumProperty VAULT_STATE = BasicEnumProperty.create("vault_state", "inactive", "active", "unlocking", "ejecting"); public static final BasicEnumProperty VAULT_STATE = BasicEnumProperty.create("vault_state", "inactive", "active", "unlocking", "ejecting");
public static final BasicEnumProperty CREAKING_HEART_STATE = BasicEnumProperty.create("creaking_heart_state", "uprooted", "dormant", "awake");
public static final BooleanProperty OMINOUS = BooleanProperty.create("ominous"); public static final BooleanProperty OMINOUS = BooleanProperty.create("ominous");
public static final BasicEnumProperty TEST_BLOCK_MODE = BasicEnumProperty.create("mode", "start", "log", "fail", "accept");
public static final BooleanProperty MAP = BooleanProperty.create("map");
} }

View File

@@ -41,6 +41,7 @@ import org.geysermc.mcprotocollib.network.helper.NettyHelper;
import org.geysermc.mcprotocollib.network.netty.MinecraftChannelInitializer; import org.geysermc.mcprotocollib.network.netty.MinecraftChannelInitializer;
import org.geysermc.mcprotocollib.network.packet.PacketProtocol; import org.geysermc.mcprotocollib.network.packet.PacketProtocol;
import org.geysermc.mcprotocollib.network.session.ClientNetworkSession; import org.geysermc.mcprotocollib.network.session.ClientNetworkSession;
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
@@ -56,7 +57,7 @@ public final class LocalSession extends ClientNetworkSession {
private final SocketAddress spoofedRemoteAddress; private final SocketAddress spoofedRemoteAddress;
public LocalSession(SocketAddress targetAddress, String clientIp, PacketProtocol protocol, Executor packetHandlerExecutor) { public LocalSession(SocketAddress targetAddress, String clientIp, MinecraftProtocol protocol, Executor packetHandlerExecutor) {
super(targetAddress, protocol, packetHandlerExecutor, null, null); super(targetAddress, protocol, packetHandlerExecutor, null, null);
this.spoofedRemoteAddress = new InetSocketAddress(clientIp, 0); this.spoofedRemoteAddress = new InetSocketAddress(clientIp, 0);
} }

View File

@@ -58,6 +58,9 @@ import org.geysermc.geyser.level.block.type.Block;
import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.level.block.type.FlowerPotBlock; import org.geysermc.geyser.level.block.type.FlowerPotBlock;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.populator.conversion.Conversion766_748;
import org.geysermc.geyser.registry.populator.conversion.Conversion776_766;
import org.geysermc.geyser.registry.populator.conversion.Conversion786_776;
import org.geysermc.geyser.registry.type.BlockMappings; import org.geysermc.geyser.registry.type.BlockMappings;
import org.geysermc.geyser.registry.type.GeyserBedrockBlock; import org.geysermc.geyser.registry.type.GeyserBedrockBlock;
@@ -119,7 +122,7 @@ public final class BlockRegistryPopulator {
var blockMappers = ImmutableMap.<ObjectIntPair<String>, Remapper>builder() var blockMappers = ImmutableMap.<ObjectIntPair<String>, Remapper>builder()
.put(ObjectIntPair.of("1_21_40", Bedrock_v748.CODEC.getProtocolVersion()), Conversion766_748::remapBlock) .put(ObjectIntPair.of("1_21_40", Bedrock_v748.CODEC.getProtocolVersion()), Conversion766_748::remapBlock)
.put(ObjectIntPair.of("1_21_50", Bedrock_v766.CODEC.getProtocolVersion()), Conversion776_766::remapBlock) .put(ObjectIntPair.of("1_21_50", Bedrock_v766.CODEC.getProtocolVersion()), Conversion776_766::remapBlock)
.put(ObjectIntPair.of("1_21_60", Bedrock_v776.CODEC.getProtocolVersion()), tag -> tag) .put(ObjectIntPair.of("1_21_60", Bedrock_v776.CODEC.getProtocolVersion()), Conversion786_776::remapBlock)
.put(ObjectIntPair.of("1_21_70", Bedrock_v786.CODEC.getProtocolVersion()), tag -> tag) .put(ObjectIntPair.of("1_21_70", Bedrock_v786.CODEC.getProtocolVersion()), tag -> tag)
.build(); .build();

View File

@@ -75,6 +75,7 @@ public final class DataComponentRegistryPopulator {
byte[] bytes = Base64.getDecoder().decode(encodedValue); byte[] bytes = Base64.getDecoder().decode(encodedValue);
ByteBuf buf = Unpooled.wrappedBuffer(bytes); ByteBuf buf = Unpooled.wrappedBuffer(bytes);
int varInt = MinecraftTypes.readVarInt(buf); int varInt = MinecraftTypes.readVarInt(buf);
System.out.println("int: " + varInt + " " + componentEntry.getKey());
DataComponentType<?> dataComponentType = DataComponentTypes.from(varInt); DataComponentType<?> dataComponentType = DataComponentTypes.from(varInt);
DataComponent<?, ?> dataComponent = dataComponentType.readDataComponent(buf); DataComponent<?, ?> dataComponent = dataComponentType.readDataComponent(buf);
@@ -84,6 +85,7 @@ public final class DataComponentRegistryPopulator {
defaultComponents.add(new DataComponents(ImmutableMap.copyOf(map))); defaultComponents.add(new DataComponents(ImmutableMap.copyOf(map)));
} }
} catch (Exception e) { } catch (Exception e) {
// TODO 1.21.5 enchantment reading is broken
throw new AssertionError("Unable to load or parse components", e); throw new AssertionError("Unable to load or parse components", e);
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2024 GeyserMC. http://geysermc.org * Copyright (c) 2024-2025 GeyserMC. http://geysermc.org
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -23,16 +23,18 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.registry.populator; package org.geysermc.geyser.registry.populator.conversion;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.Blocks;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static org.geysermc.geyser.registry.populator.conversion.ConversionHelper.withName;
import static org.geysermc.geyser.registry.populator.conversion.ConversionHelper.withoutStates;
public class Conversion766_748 { public class Conversion766_748 {
static List<String> PALE_WOODEN_BLOCKS = new ArrayList<>(); static List<String> PALE_WOODEN_BLOCKS = new ArrayList<>();
static List<String> OTHER_NEW_BLOCKS = new ArrayList<>(); static List<String> OTHER_NEW_BLOCKS = new ArrayList<>();
@@ -84,7 +86,7 @@ public class Conversion766_748 {
OTHER_NEW_BLOCKS.add("resin_brick_double_slab"); OTHER_NEW_BLOCKS.add("resin_brick_double_slab");
} }
static NbtMap remapBlock(NbtMap tag) { public static NbtMap remapBlock(NbtMap tag) {
// First: Downgrade from 1.21.60 -> 1.21.50 // First: Downgrade from 1.21.60 -> 1.21.50
tag = Conversion776_766.remapBlock(tag); tag = Conversion776_766.remapBlock(tag);
@@ -116,17 +118,4 @@ public class Conversion766_748 {
return tag; return tag;
} }
static NbtMap withName(NbtMap tag, String name) {
NbtMapBuilder builder = tag.toBuilder();
builder.replace("name", "minecraft:" + name);
return builder.build();
}
static NbtMap withoutStates(String name) {
NbtMapBuilder tagBuilder = NbtMap.builder();
tagBuilder.putString("name", "minecraft:" + name);
tagBuilder.putCompound("states", NbtMap.builder().build());
return tagBuilder.build();
}
} }

View File

@@ -23,7 +23,7 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.registry.populator; package org.geysermc.geyser.registry.populator.conversion;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
@@ -31,6 +31,10 @@ import org.cloudburstmc.nbt.NbtMapBuilder;
public class Conversion776_766 { public class Conversion776_766 {
public static NbtMap remapBlock(NbtMap tag) { public static NbtMap remapBlock(NbtMap tag) {
// First: Downgrade from 1.21.70
tag = Conversion786_776.remapBlock(tag);
final String name = tag.getString("name"); final String name = tag.getString("name");
if (name.equals("minecraft:creaking_heart")) { if (name.equals("minecraft:creaking_heart")) {

View File

@@ -0,0 +1,60 @@
/*
* 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;
import static org.geysermc.geyser.registry.populator.conversion.ConversionHelper.withName;
import static org.geysermc.geyser.registry.populator.conversion.ConversionHelper.withoutStates;
public class Conversion786_776 {
public static NbtMap remapBlock(NbtMap nbtMap) {
final String name = nbtMap.getString("name");
if (name.equals("minecraft:bush")) {
return withName(nbtMap, "fern");
}
if (name.equals("minecraft:firefly_bush")) {
return withName(nbtMap, "deadbush");
}
if (name.equals("minecraft:tall_dry_grass") || name.equals("minecraft:short_dry_grass")) {
return withName(nbtMap, "short_grass");
}
if (name.equals("minecraft:cactus_flower")) {
return withName(nbtMap, "unknown");
}
if (name.equals("minecraft:leaf_litter") || name.equals("minecraft:wildflowers")) {
return withoutStates("unknown");
}
return nbtMap;
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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;
import org.cloudburstmc.nbt.NbtMapBuilder;
// A variety of methods to help with re-mapping blocks and items to older versions.
public class ConversionHelper {
static NbtMap withName(NbtMap tag, String name) {
NbtMapBuilder builder = tag.toBuilder();
builder.replace("name", "minecraft:" + name);
return builder.build();
}
static NbtMap withoutStates(String name) {
NbtMapBuilder tagBuilder = NbtMap.builder();
tagBuilder.putString("name", "minecraft:" + name);
tagBuilder.putCompound("states", NbtMap.EMPTY);
return tagBuilder.build();
}
}

View File

@@ -141,6 +141,7 @@ public final class BlockTag {
public static final Tag<Block> FENCE_GATES = create("fence_gates"); public static final Tag<Block> FENCE_GATES = create("fence_gates");
public static final Tag<Block> UNSTABLE_BOTTOM_CENTER = create("unstable_bottom_center"); public static final Tag<Block> UNSTABLE_BOTTOM_CENTER = create("unstable_bottom_center");
public static final Tag<Block> MUSHROOM_GROW_BLOCK = create("mushroom_grow_block"); public static final Tag<Block> MUSHROOM_GROW_BLOCK = create("mushroom_grow_block");
public static final Tag<Block> EDIBLE_FOR_SHEEP = create("edible_for_sheep");
public static final Tag<Block> INFINIBURN_OVERWORLD = create("infiniburn_overworld"); public static final Tag<Block> INFINIBURN_OVERWORLD = create("infiniburn_overworld");
public static final Tag<Block> INFINIBURN_NETHER = create("infiniburn_nether"); public static final Tag<Block> INFINIBURN_NETHER = create("infiniburn_nether");
public static final Tag<Block> INFINIBURN_END = create("infiniburn_end"); public static final Tag<Block> INFINIBURN_END = create("infiniburn_end");
@@ -171,6 +172,7 @@ public final class BlockTag {
public static final Tag<Block> MINEABLE_PICKAXE = create("mineable/pickaxe"); public static final Tag<Block> MINEABLE_PICKAXE = create("mineable/pickaxe");
public static final Tag<Block> MINEABLE_SHOVEL = create("mineable/shovel"); public static final Tag<Block> MINEABLE_SHOVEL = create("mineable/shovel");
public static final Tag<Block> SWORD_EFFICIENT = create("sword_efficient"); public static final Tag<Block> SWORD_EFFICIENT = create("sword_efficient");
public static final Tag<Block> SWORD_INSTANTLY_MINES = create("sword_instantly_mines");
public static final Tag<Block> NEEDS_DIAMOND_TOOL = create("needs_diamond_tool"); public static final Tag<Block> NEEDS_DIAMOND_TOOL = create("needs_diamond_tool");
public static final Tag<Block> NEEDS_IRON_TOOL = create("needs_iron_tool"); public static final Tag<Block> NEEDS_IRON_TOOL = create("needs_iron_tool");
public static final Tag<Block> NEEDS_STONE_TOOL = create("needs_stone_tool"); public static final Tag<Block> NEEDS_STONE_TOOL = create("needs_stone_tool");
@@ -200,13 +202,15 @@ public final class BlockTag {
public static final Tag<Block> WOLVES_SPAWNABLE_ON = create("wolves_spawnable_on"); public static final Tag<Block> WOLVES_SPAWNABLE_ON = create("wolves_spawnable_on");
public static final Tag<Block> FROGS_SPAWNABLE_ON = create("frogs_spawnable_on"); public static final Tag<Block> FROGS_SPAWNABLE_ON = create("frogs_spawnable_on");
public static final Tag<Block> BATS_SPAWNABLE_ON = create("bats_spawnable_on"); public static final Tag<Block> BATS_SPAWNABLE_ON = create("bats_spawnable_on");
public static final Tag<Block> CAMELS_SPAWNABLE_ON = create("camels_spawnable_on");
public static final Tag<Block> AZALEA_GROWS_ON = create("azalea_grows_on"); public static final Tag<Block> AZALEA_GROWS_ON = create("azalea_grows_on");
public static final Tag<Block> CONVERTABLE_TO_MUD = create("convertable_to_mud"); public static final Tag<Block> CONVERTABLE_TO_MUD = create("convertable_to_mud");
public static final Tag<Block> MANGROVE_LOGS_CAN_GROW_THROUGH = create("mangrove_logs_can_grow_through"); public static final Tag<Block> MANGROVE_LOGS_CAN_GROW_THROUGH = create("mangrove_logs_can_grow_through");
public static final Tag<Block> MANGROVE_ROOTS_CAN_GROW_THROUGH = create("mangrove_roots_can_grow_through"); public static final Tag<Block> MANGROVE_ROOTS_CAN_GROW_THROUGH = create("mangrove_roots_can_grow_through");
public static final Tag<Block> DEAD_BUSH_MAY_PLACE_ON = create("dead_bush_may_place_on"); public static final Tag<Block> DRY_VEGETATION_MAY_PLACE_ON = create("dry_vegetation_may_place_on");
public static final Tag<Block> SNAPS_GOAT_HORN = create("snaps_goat_horn"); public static final Tag<Block> SNAPS_GOAT_HORN = create("snaps_goat_horn");
public static final Tag<Block> REPLACEABLE_BY_TREES = create("replaceable_by_trees"); public static final Tag<Block> REPLACEABLE_BY_TREES = create("replaceable_by_trees");
public static final Tag<Block> REPLACEABLE_BY_MUSHROOMS = create("replaceable_by_mushrooms");
public static final Tag<Block> SNOW_LAYER_CANNOT_SURVIVE_ON = create("snow_layer_cannot_survive_on"); public static final Tag<Block> SNOW_LAYER_CANNOT_SURVIVE_ON = create("snow_layer_cannot_survive_on");
public static final Tag<Block> SNOW_LAYER_CAN_SURVIVE_ON = create("snow_layer_can_survive_on"); public static final Tag<Block> SNOW_LAYER_CAN_SURVIVE_ON = create("snow_layer_can_survive_on");
public static final Tag<Block> INVALID_SPAWN_INSIDE = create("invalid_spawn_inside"); public static final Tag<Block> INVALID_SPAWN_INSIDE = create("invalid_spawn_inside");
@@ -219,6 +223,7 @@ public final class BlockTag {
public static final Tag<Block> MAINTAINS_FARMLAND = create("maintains_farmland"); public static final Tag<Block> MAINTAINS_FARMLAND = create("maintains_farmland");
public static final Tag<Block> BLOCKS_WIND_CHARGE_EXPLOSIONS = create("blocks_wind_charge_explosions"); public static final Tag<Block> BLOCKS_WIND_CHARGE_EXPLOSIONS = create("blocks_wind_charge_explosions");
public static final Tag<Block> DOES_NOT_BLOCK_HOPPERS = create("does_not_block_hoppers"); public static final Tag<Block> DOES_NOT_BLOCK_HOPPERS = create("does_not_block_hoppers");
public static final Tag<Block> PLAYS_AMBIENT_DESERT_BLOCK_SOUNDS = create("plays_ambient_desert_block_sounds");
public static final Tag<Block> AIR = create("air"); public static final Tag<Block> AIR = create("air");
private BlockTag() {} private BlockTag() {}

View File

@@ -76,6 +76,7 @@ public final class ItemTag {
public static final Tag<Item> LEAVES = create("leaves"); public static final Tag<Item> LEAVES = create("leaves");
public static final Tag<Item> TRAPDOORS = create("trapdoors"); public static final Tag<Item> TRAPDOORS = create("trapdoors");
public static final Tag<Item> SMALL_FLOWERS = create("small_flowers"); public static final Tag<Item> SMALL_FLOWERS = create("small_flowers");
public static final Tag<Item> FLOWERS = create("flowers");
public static final Tag<Item> BEDS = create("beds"); public static final Tag<Item> BEDS = create("beds");
public static final Tag<Item> FENCES = create("fences"); public static final Tag<Item> FENCES = create("fences");
public static final Tag<Item> PIGLIN_REPELLENTS = create("piglin_repellents"); public static final Tag<Item> PIGLIN_REPELLENTS = create("piglin_repellents");
@@ -85,6 +86,7 @@ public final class ItemTag {
public static final Tag<Item> DUPLICATES_ALLAYS = create("duplicates_allays"); public static final Tag<Item> DUPLICATES_ALLAYS = create("duplicates_allays");
public static final Tag<Item> BREWING_FUEL = create("brewing_fuel"); public static final Tag<Item> BREWING_FUEL = create("brewing_fuel");
public static final Tag<Item> SHULKER_BOXES = create("shulker_boxes"); public static final Tag<Item> SHULKER_BOXES = create("shulker_boxes");
public static final Tag<Item> EGGS = create("eggs");
public static final Tag<Item> MEAT = create("meat"); public static final Tag<Item> MEAT = create("meat");
public static final Tag<Item> SNIFFER_FOOD = create("sniffer_food"); public static final Tag<Item> SNIFFER_FOOD = create("sniffer_food");
public static final Tag<Item> PIGLIN_FOOD = create("piglin_food"); public static final Tag<Item> PIGLIN_FOOD = create("piglin_food");
@@ -181,6 +183,7 @@ public final class ItemTag {
public static final Tag<Item> DYEABLE = create("dyeable"); public static final Tag<Item> DYEABLE = create("dyeable");
public static final Tag<Item> FURNACE_MINECART_FUEL = create("furnace_minecart_fuel"); public static final Tag<Item> FURNACE_MINECART_FUEL = create("furnace_minecart_fuel");
public static final Tag<Item> BUNDLES = create("bundles"); public static final Tag<Item> BUNDLES = create("bundles");
public static final Tag<Item> BOOK_CLONING_TARGET = create("book_cloning_target");
public static final Tag<Item> SKELETON_PREFERRED_WEAPONS = create("skeleton_preferred_weapons"); public static final Tag<Item> SKELETON_PREFERRED_WEAPONS = create("skeleton_preferred_weapons");
public static final Tag<Item> DROWNED_PREFERRED_WEAPONS = create("drowned_preferred_weapons"); public static final Tag<Item> DROWNED_PREFERRED_WEAPONS = create("drowned_preferred_weapons");
public static final Tag<Item> PIGLIN_PREFERRED_WEAPONS = create("piglin_preferred_weapons"); public static final Tag<Item> PIGLIN_PREFERRED_WEAPONS = create("piglin_preferred_weapons");

View File

@@ -168,6 +168,9 @@ public final class ItemTranslator {
public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents customComponents) { public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents customComponents) {
BedrockItemBuilder nbtBuilder = new BedrockItemBuilder(); BedrockItemBuilder nbtBuilder = new BedrockItemBuilder();
// TODO 1.21.5:
// - Hiding components
// Populates default components that aren't sent over the network // Populates default components that aren't sent over the network
DataComponents components = javaItem.gatherComponents(customComponents); DataComponents components = javaItem.gatherComponents(customComponents);
@@ -180,22 +183,22 @@ public final class ItemTranslator {
PotionContents potionContents = components.get(DataComponentTypes.POTION_CONTENTS); PotionContents potionContents = components.get(DataComponentTypes.POTION_CONTENTS);
// Make custom effect information visible // Make custom effect information visible
// Ignore when item have "hide_additional_tooltip" component // Ignore when item have "hide_additional_tooltip" component
if (potionContents != null && components.get(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) == null) { if (potionContents != null) { // && components.get(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) == null) {
customName += getPotionEffectInfo(potionContents, session.locale()); customName += getPotionEffectInfo(potionContents, session.locale());
} }
nbtBuilder.setCustomName(customName); nbtBuilder.setCustomName(customName);
} }
boolean hideTooltips = components.get(DataComponentTypes.HIDE_TOOLTIP) != null; //boolean hideTooltips = components.get(DataComponentTypes.HIDE_TOOLTIP) != null;
ItemAttributeModifiers attributeModifiers = components.get(DataComponentTypes.ATTRIBUTE_MODIFIERS); ItemAttributeModifiers attributeModifiers = components.get(DataComponentTypes.ATTRIBUTE_MODIFIERS);
if (attributeModifiers != null && attributeModifiers.isShowInTooltip() && !hideTooltips) { if (attributeModifiers != null) { //&& attributeModifiers.isShowInTooltip() && !hideTooltips) {
// only add if attribute modifiers do not indicate to hide them // only add if attribute modifiers do not indicate to hide them
addAttributeLore(session, attributeModifiers, nbtBuilder, session.locale()); addAttributeLore(session, attributeModifiers, nbtBuilder, session.locale());
} }
if (session.isAdvancedTooltips() && !hideTooltips) { if (session.isAdvancedTooltips()) { //&& !hideTooltips) {
addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale()); addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale());
} }
@@ -545,7 +548,8 @@ public final class ItemTranslator {
if (!customNameOnly) { if (!customNameOnly) {
PotionContents potionContents = components.get(DataComponentTypes.POTION_CONTENTS); PotionContents potionContents = components.get(DataComponentTypes.POTION_CONTENTS);
if (potionContents != null) { if (potionContents != null) {
String potionName = getPotionName(potionContents, mapping, components.get(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) != null, session.locale()); // TODO 1.21.5
String potionName = getPotionName(potionContents, mapping, false /*components.get(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) != null */, session.locale());
if (potionName != null) { if (potionName != null) {
return ChatColor.RESET + ChatColor.ESCAPE + translationColor + potionName; return ChatColor.RESET + ChatColor.ESCAPE + translationColor + potionName;
} }

View File

@@ -30,7 +30,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import org.cloudburstmc.math.vector.Vector3d; import org.cloudburstmc.math.vector.Vector3d;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
@@ -41,8 +40,6 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.InventoryTra
import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.LegacySetItemSlotData; import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.LegacySetItemSlotData;
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket; import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventoryTransactionPacket; import org.cloudburstmc.protocol.bedrock.packet.InventoryTransactionPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.Entity;
@@ -52,7 +49,6 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory; import org.geysermc.geyser.inventory.PlayerInventory;
import org.geysermc.geyser.inventory.click.Click; import org.geysermc.geyser.inventory.click.Click;
import org.geysermc.geyser.inventory.item.GeyserInstrument;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.type.BlockItem; import org.geysermc.geyser.item.type.BlockItem;
import org.geysermc.geyser.item.type.BoatItem; import org.geysermc.geyser.item.type.BoatItem;
@@ -78,16 +74,12 @@ import org.geysermc.geyser.util.CooldownUtils;
import org.geysermc.geyser.util.EntityUtils; import org.geysermc.geyser.util.EntityUtils;
import org.geysermc.geyser.util.InteractionResult; import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.geyser.util.InventoryUtils;
import org.geysermc.geyser.util.SoundUtils;
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; 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.Instrument;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;
@@ -388,29 +380,30 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
session.setCurrentBook(packet.getItemInHand()); session.setCurrentBook(packet.getItemInHand());
} else if (session.getPlayerInventory().getItemInHand().asItem() == Items.GOAT_HORN) { } else if (session.getPlayerInventory().getItemInHand().asItem() == Items.GOAT_HORN) {
// Temporary workaround while we don't have full item/block use tracking. // Temporary workaround while we don't have full item/block use tracking.
// TODO 1.21.5
if (!session.getWorldCache().hasCooldown(session.getPlayerInventory().getItemInHand())) { if (!session.getWorldCache().hasCooldown(session.getPlayerInventory().getItemInHand())) {
Holder<Instrument> holder = session.getPlayerInventory() // Holder<Instrument> holder = session.getPlayerInventory()
.getItemInHand() // .getItemInHand()
.getComponent(DataComponentTypes.INSTRUMENT); // .getComponent(DataComponentTypes.INSTRUMENT);
if (holder != null) { // if (holder != null) {
GeyserInstrument instrument = GeyserInstrument.fromHolder(session, holder); // GeyserInstrument instrument = GeyserInstrument.fromComponent(session, holder);
if (instrument.bedrockInstrument() != null) { // if (instrument.bedrockInstrument() != null) {
// BDS uses a LevelSoundEvent2Packet, but that doesn't work here... (as of 1.21.20) // // BDS uses a LevelSoundEvent2Packet, but that doesn't work here... (as of 1.21.20)
LevelSoundEventPacket soundPacket = new LevelSoundEventPacket(); // LevelSoundEventPacket soundPacket = new LevelSoundEventPacket();
soundPacket.setSound(SoundEvent.valueOf("GOAT_CALL_" + instrument.bedrockInstrument().ordinal())); // soundPacket.setSound(SoundEvent.valueOf("GOAT_CALL_" + instrument.bedrockInstrument().ordinal()));
soundPacket.setPosition(session.getPlayerEntity().getPosition()); // soundPacket.setPosition(session.getPlayerEntity().getPosition());
soundPacket.setIdentifier("minecraft:player"); // soundPacket.setIdentifier("minecraft:player");
soundPacket.setExtraData(-1); // soundPacket.setExtraData(-1);
session.sendUpstreamPacket(soundPacket); // session.sendUpstreamPacket(soundPacket);
} else { // } else {
PlaySoundPacket playSoundPacket = new PlaySoundPacket(); // PlaySoundPacket playSoundPacket = new PlaySoundPacket();
playSoundPacket.setPosition(session.getPlayerEntity().position()); // playSoundPacket.setPosition(session.getPlayerEntity().position());
playSoundPacket.setSound(SoundUtils.translatePlaySound(instrument.soundEvent())); // playSoundPacket.setSound(SoundUtils.translatePlaySound(instrument.soundEvent()));
playSoundPacket.setPitch(1.0F); // playSoundPacket.setPitch(1.0F);
playSoundPacket.setVolume(instrument.range() / 16.0F); // playSoundPacket.setVolume(instrument.range() / 16.0F);
session.sendUpstreamPacket(playSoundPacket); // session.sendUpstreamPacket(playSoundPacket);
} // }
} // }
} }
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org * Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
* @link https://github.com/GeyserMC/Geyser * @link https://github.com/GeyserMC/Geyser
*/ */
package org.geysermc.geyser.translator.protocol.java.entity.spawn; package org.geysermc.geyser.translator.protocol.java.entity;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
@@ -47,7 +47,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.object.FallingBlockD
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.ProjectileData; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.ProjectileData;
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.WardenData; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.WardenData;
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundAddEntityPacket;
@Translator(packet = ClientboundAddEntityPacket.class) @Translator(packet = ClientboundAddEntityPacket.class)
public class JavaAddEntityTranslator extends PacketTranslator<ClientboundAddEntityPacket> { public class JavaAddEntityTranslator extends PacketTranslator<ClientboundAddEntityPacket> {

View File

@@ -1,49 +0,0 @@
/*
* Copyright (c) 2019-2022 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.translator.protocol.java.entity.spawn;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddExperienceOrbPacket;
import org.cloudburstmc.math.vector.Vector3f;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.type.ExpOrbEntity;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@Translator(packet = ClientboundAddExperienceOrbPacket.class)
public class JavaAddExperienceOrbTranslator extends PacketTranslator<ClientboundAddExperienceOrbPacket> {
@Override
public void translate(GeyserSession session, ClientboundAddExperienceOrbPacket packet) {
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
Entity entity = new ExpOrbEntity(
session, packet.getExp(), packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), position
);
session.getEntityCache().spawnEntity(entity);
}
}

View File

@@ -73,11 +73,11 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
public static void openMerchant(GeyserSession session, ClientboundMerchantOffersPacket packet, MerchantContainer merchantInventory) { public static void openMerchant(GeyserSession session, ClientboundMerchantOffersPacket packet, MerchantContainer merchantInventory) {
// Retrieve the fake villager involved in the trade, and update its metadata to match with the window information // Retrieve the fake villager involved in the trade, and update its metadata to match with the window information
merchantInventory.setVillagerTrades(packet.getTrades()); merchantInventory.setVillagerTrades(packet.getOffers());
merchantInventory.setTradeExperience(packet.getExperience()); merchantInventory.setTradeExperience(packet.getVillagerXp());
Entity villager = merchantInventory.getVillager(); Entity villager = merchantInventory.getVillager();
if (packet.isRegularVillager()) { if (packet.isShowProgress()) {
villager.getDirtyMetadata().put(EntityDataTypes.TRADE_TIER, packet.getVillagerLevel() - 1); villager.getDirtyMetadata().put(EntityDataTypes.TRADE_TIER, packet.getVillagerLevel() - 1);
villager.getDirtyMetadata().put(EntityDataTypes.MAX_TRADE_TIER, 4); villager.getDirtyMetadata().put(EntityDataTypes.MAX_TRADE_TIER, 4);
} else { } else {
@@ -85,7 +85,7 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
villager.getDirtyMetadata().put(EntityDataTypes.TRADE_TIER, 0); villager.getDirtyMetadata().put(EntityDataTypes.TRADE_TIER, 0);
villager.getDirtyMetadata().put(EntityDataTypes.MAX_TRADE_TIER, 0); villager.getDirtyMetadata().put(EntityDataTypes.MAX_TRADE_TIER, 0);
} }
villager.getDirtyMetadata().put(EntityDataTypes.TRADE_EXPERIENCE, packet.getExperience()); villager.getDirtyMetadata().put(EntityDataTypes.TRADE_EXPERIENCE, packet.getVillagerXp());
villager.updateBedrockMetadata(); villager.updateBedrockMetadata();
// Construct the packet that opens the trading window // Construct the packet that opens the trading window
@@ -101,29 +101,29 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
updateTradePacket.setTraderUniqueEntityId(villager.getGeyserId()); updateTradePacket.setTraderUniqueEntityId(villager.getGeyserId());
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
boolean addExtraTrade = packet.isRegularVillager() && packet.getVillagerLevel() < 5; boolean addExtraTrade = packet.isShowProgress() && packet.getVillagerLevel() < 5;
List<NbtMap> tags = new ArrayList<>(addExtraTrade ? packet.getTrades().length + 1 : packet.getTrades().length); List<NbtMap> tags = new ArrayList<>(addExtraTrade ? packet.getOffers().size() + 1 : packet.getOffers().size());
for (int i = 0; i < packet.getTrades().length; i++) { for (int i = 0; i < packet.getOffers().size(); i++) {
VillagerTrade trade = packet.getTrades()[i]; VillagerTrade trade = packet.getOffers().get(i);
NbtMapBuilder recipe = NbtMap.builder(); NbtMapBuilder recipe = NbtMap.builder();
recipe.putInt("netId", i + 1); recipe.putInt("netId", i + 1);
recipe.putInt("maxUses", trade.isTradeDisabled() ? 0 : trade.getMaxUses()); recipe.putInt("maxUses", trade.isOutOfStock() ? 0 : trade.getMaxUses());
recipe.putInt("traderExp", trade.getXp()); recipe.putInt("traderExp", trade.getXp());
recipe.putFloat("priceMultiplierA", trade.getPriceMultiplier()); recipe.putFloat("priceMultiplierA", trade.getPriceMultiplier());
recipe.putFloat("priceMultiplierB", 0.0f); recipe.putFloat("priceMultiplierB", 0.0f);
recipe.put("sell", getItemTag(session, trade.getOutput())); recipe.put("sell", getItemTag(session, trade.getResult()));
// The buy count before demand and special price adjustments // The buy count before demand and special price adjustments
// The first input CAN be null as of Java 1.19.0/Bedrock 1.19.10 // The first input CAN be null as of Java 1.19.0/Bedrock 1.19.10
// Replicable item: https://gist.github.com/Camotoy/3f3f23d1f80981d1b4472bdb23bba698 from https://github.com/GeyserMC/Geyser/issues/3171 // Replicable item: https://gist.github.com/Camotoy/3f3f23d1f80981d1b4472bdb23bba698 from https://github.com/GeyserMC/Geyser/issues/3171
recipe.putInt("buyCountA", trade.getFirstInput() != null ? Math.max(trade.getFirstInput().getAmount(), 0) : 0); recipe.putInt("buyCountA", trade.getItemCostA() != null ? Math.max(trade.getItemCostA().count(), 0) : 0);
recipe.putInt("buyCountB", trade.getSecondInput() != null ? Math.max(trade.getSecondInput().getAmount(), 0) : 0); recipe.putInt("buyCountB", trade.getItemCostB() != null ? Math.max(trade.getItemCostB().count(), 0) : 0);
recipe.putInt("demand", trade.getDemand()); // Seems to have no effect recipe.putInt("demand", trade.getDemand()); // Seems to have no effect
recipe.putInt("tier", packet.getVillagerLevel() > 0 ? packet.getVillagerLevel() - 1 : 0); // -1 crashes client recipe.putInt("tier", packet.getVillagerLevel() > 0 ? packet.getVillagerLevel() - 1 : 0); // -1 crashes client
recipe.put("buyA", getItemTag(session, trade.getFirstInput(), trade.getSpecialPrice(), trade.getDemand(), trade.getPriceMultiplier())); recipe.put("buyA", getItemTag(session, toItemStack(trade.getItemCostA()), trade.getSpecialPriceDiff(), trade.getDemand(), trade.getPriceMultiplier()));
recipe.put("buyB", getItemTag(session, trade.getSecondInput())); recipe.put("buyB", getItemTag(session, toItemStack(trade.getItemCostB())));
recipe.putInt("uses", trade.getNumUses()); recipe.putInt("uses", trade.getUses());
recipe.putByte("rewardExp", (byte) 1); recipe.putByte("rewardExp", (byte) 1);
tags.add(recipe.build()); tags.add(recipe.build());
} }
@@ -158,6 +158,11 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
session.sendUpstreamPacket(updateTradePacket); session.sendUpstreamPacket(updateTradePacket);
} }
private static ItemStack toItemStack(VillagerTrade.ItemCost itemCost) {
// TODO 1.21.5 figure out how to deal with components here!
return new ItemStack(itemCost.itemId(), itemCost.count());
}
private static NbtMap getItemTag(GeyserSession session, ItemStack stack) { private static NbtMap getItemTag(GeyserSession session, ItemStack stack) {
if (InventoryUtils.isEmpty(stack)) { // Negative item counts appear as air on Java if (InventoryUtils.isEmpty(stack)) { // Negative item counts appear as air on Java
return NbtMap.EMPTY; return NbtMap.EMPTY;

View File

@@ -59,23 +59,23 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
// However, it seems most server software (at least Spigot and Paper) did not go along with this // However, it seems most server software (at least Spigot and Paper) did not go along with this
// As a result many developers use these packets for the opposite of what their names implies // As a result many developers use these packets for the opposite of what their names implies
// Behavior last verified with Java 1.19.4 and Bedrock 1.19.71 // Behavior last verified with Java 1.19.4 and Bedrock 1.19.71
case START_RAIN: case START_RAINING:
session.updateRain(0); session.updateRain(0);
break; break;
case STOP_RAIN: case STOP_RAINING:
session.updateRain(1); session.updateRain(1);
break; break;
case RAIN_STRENGTH: case RAIN_LEVEL_CHANGE:
// This is the rain strength on LevelEventType.START_RAINING, but can be any value on LevelEventType.STOP_RAINING // This is the rain strength on LevelEventType.START_RAINING, but can be any value on LevelEventType.STOP_RAINING
float rainStrength = ((RainStrengthValue) packet.getValue()).getStrength(); float rainStrength = ((RainStrengthValue) packet.getValue()).getStrength();
session.updateRain(rainStrength); session.updateRain(rainStrength);
break; break;
case THUNDER_STRENGTH: case THUNDER_LEVEL_CHANGE:
// See above, same process // See above, same process
float thunderStrength = ((ThunderStrengthValue) packet.getValue()).getStrength(); float thunderStrength = ((ThunderStrengthValue) packet.getValue()).getStrength();
session.updateThunder(thunderStrength); session.updateThunder(thunderStrength);
break; break;
case CHANGE_GAMEMODE: case CHANGE_GAME_MODE:
GameMode gameMode = (GameMode) packet.getValue(); GameMode gameMode = (GameMode) packet.getValue();
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
@@ -100,7 +100,7 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
// Update the crafting grid to add/remove barriers for creative inventory // Update the crafting grid to add/remove barriers for creative inventory
PlayerInventoryTranslator.updateCraftingGrid(session, session.getPlayerInventory()); PlayerInventoryTranslator.updateCraftingGrid(session, session.getPlayerInventory());
break; break;
case ENTER_CREDITS: case WIN_GAME:
switch ((EnterCreditsValue) packet.getValue()) { switch ((EnterCreditsValue) packet.getValue()) {
case SEEN_BEFORE -> { case SEEN_BEFORE -> {
ServerboundClientCommandPacket javaRespawnPacket = new ServerboundClientCommandPacket(ClientCommand.RESPAWN); ServerboundClientCommandPacket javaRespawnPacket = new ServerboundClientCommandPacket(ClientCommand.RESPAWN);
@@ -114,7 +114,7 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
} }
} }
break; break;
case AFFECTED_BY_ELDER_GUARDIAN: case GUARDIAN_ELDER_EFFECT:
// note: There is a ElderGuardianEffectValue that determines if a sound should be made or not, // note: There is a ElderGuardianEffectValue that determines if a sound should be made or not,
// but that doesn't seem to be controllable on Bedrock Edition // but that doesn't seem to be controllable on Bedrock Edition
EntityEventPacket eventPacket = new EntityEventPacket(); EntityEventPacket eventPacket = new EntityEventPacket();
@@ -123,18 +123,18 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
eventPacket.setRuntimeEntityId(entity.getGeyserId()); eventPacket.setRuntimeEntityId(entity.getGeyserId());
session.sendUpstreamPacket(eventPacket); session.sendUpstreamPacket(eventPacket);
break; break;
case ENABLE_RESPAWN_SCREEN: case IMMEDIATE_RESPAWN:
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket(); GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
gamerulePacket.getGameRules().add(new GameRuleData<>("doimmediaterespawn", gamerulePacket.getGameRules().add(new GameRuleData<>("doimmediaterespawn",
packet.getValue() == RespawnScreenValue.IMMEDIATE_RESPAWN)); packet.getValue() == RespawnScreenValue.IMMEDIATE_RESPAWN));
session.sendUpstreamPacket(gamerulePacket); session.sendUpstreamPacket(gamerulePacket);
break; break;
case INVALID_BED: case NO_RESPAWN_BLOCK_AVAILABLE:
// Not sent as a proper message? Odd. // Not sent as a proper message? Odd.
session.sendMessage(MinecraftLocale.getLocaleString("block.minecraft.spawn.not_valid", session.sendMessage(MinecraftLocale.getLocaleString("block.minecraft.spawn.not_valid",
session.locale())); session.locale()));
break; break;
case ARROW_HIT_PLAYER: case PLAY_ARROW_HIT_SOUND:
PlaySoundPacket arrowSoundPacket = new PlaySoundPacket(); PlaySoundPacket arrowSoundPacket = new PlaySoundPacket();
arrowSoundPacket.setSound("random.orb"); arrowSoundPacket.setSound("random.orb");
arrowSoundPacket.setPitch(0.5f); arrowSoundPacket.setPitch(0.5f);
@@ -143,9 +143,9 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
session.sendUpstreamPacket(arrowSoundPacket); session.sendUpstreamPacket(arrowSoundPacket);
break; break;
default: default:
// DEMO_MESSAGE - for JE game demo // DEMO_EVENT - for JE game demo
// LEVEL_CHUNKS_LOAD_START - ??? // LEVEL_CHUNKS_LOAD_START - ???
// PUFFERFISH_STING_SOUND - doesn't exist on bedrock // PUFFER_FISH_STING - doesn't exist on bedrock
break; break;
} }
} }

View File

@@ -156,7 +156,8 @@ public class StructureBlockUtils {
settings.getIntegritySeed(), settings.getIntegritySeed(),
settings.isIgnoringEntities(), settings.isIgnoringEntities(),
false, false,
boundingBoxVisible boundingBoxVisible,
false // TODO 1.21.5 test
); );
session.sendDownstreamPacket(structureBlockPacket); session.sendDownstreamPacket(structureBlockPacket);

File diff suppressed because it is too large Load Diff

View File

@@ -25,40 +25,18 @@
package org.geysermc.geyser.scoreboard.network; package org.geysermc.geyser.scoreboard.network;
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNextPacket;
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNextPacketMatch;
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNextPacketType;
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.assertNoNextPacket;
import static org.geysermc.geyser.scoreboard.network.util.GeyserMockContextScoreboard.mockContextScoreboard;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.cloudburstmc.protocol.bedrock.data.ScoreInfo;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket; import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket;
import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket; import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket;
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket; import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket;
import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket;
import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetDisplayObjectivePacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket; import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetScorePacket;
import org.geysermc.geyser.entity.type.living.monster.EnderDragonPartEntity; import org.geysermc.geyser.entity.type.living.monster.EnderDragonPartEntity;
import org.geysermc.geyser.session.cache.EntityCache;
import org.geysermc.geyser.translator.protocol.java.entity.JavaRemoveEntitiesTranslator;
import org.geysermc.geyser.translator.protocol.java.entity.JavaSetEntityDataTranslator; import org.geysermc.geyser.translator.protocol.java.entity.JavaSetEntityDataTranslator;
import org.geysermc.geyser.translator.protocol.java.entity.player.JavaPlayerInfoUpdateTranslator; import org.geysermc.geyser.translator.protocol.java.entity.player.JavaPlayerInfoUpdateTranslator;
import org.geysermc.geyser.translator.protocol.java.entity.spawn.JavaAddEntityTranslator; import org.geysermc.geyser.translator.protocol.java.entity.JavaAddEntityTranslator;
import org.geysermc.geyser.translator.protocol.java.entity.spawn.JavaAddExperienceOrbTranslator;
import org.geysermc.geyser.translator.protocol.java.scoreboard.JavaSetDisplayObjectiveTranslator;
import org.geysermc.geyser.translator.protocol.java.scoreboard.JavaSetObjectiveTranslator;
import org.geysermc.geyser.translator.protocol.java.scoreboard.JavaSetPlayerTeamTranslator; import org.geysermc.geyser.translator.protocol.java.scoreboard.JavaSetPlayerTeamTranslator;
import org.geysermc.geyser.translator.protocol.java.scoreboard.JavaSetScoreTranslator;
import org.geysermc.mcprotocollib.auth.GameProfile; import org.geysermc.mcprotocollib.auth.GameProfile;
import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntry; import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntry;
import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntryAction; import org.geysermc.mcprotocollib.protocol.data.game.PlayerListEntryAction;
@@ -71,53 +49,55 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.CollisionRule; import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.CollisionRule;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.NameTagVisibility; import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.NameTagVisibility;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ObjectiveAction;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreType;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.ScoreboardPosition;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamAction; import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamAction;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor; import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundRemoveEntitiesPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundSetEntityDataPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddExperienceOrbPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetDisplayObjectivePacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetObjectivePacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetPlayerTeamPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetPlayerTeamPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.scoreboard.ClientboundSetScorePacket;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.EnumSet;
import java.util.Optional;
import java.util.UUID;
import static org.geysermc.geyser.scoreboard.network.util.AssertUtils.*;
import static org.geysermc.geyser.scoreboard.network.util.GeyserMockContextScoreboard.mockContextScoreboard;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
/** /**
* Tests for issues reported on GitHub. * Tests for issues reported on GitHub.
*/ */
public class ScoreboardIssueTests { public class ScoreboardIssueTests {
/** // TODO 1.21.5
* Test for <a href="https://github.com/GeyserMC/Geyser/issues/5075">#5075</a> // /**
*/ // * Test for <a href="https://github.com/GeyserMC/Geyser/issues/5075">#5075</a>
@Test // */
void entityWithoutUuid() { // @Test
// experience orbs are the only known entities without an uuid, see Entity#teamIdentifier for more info // void entityWithoutUuid() {
mockContextScoreboard(context -> { // // experience orbs are the only known entities without an uuid, see Entity#teamIdentifier for more info
var addExperienceOrbTranslator = new JavaAddExperienceOrbTranslator(); // mockContextScoreboard(context -> {
var removeEntitiesTranslator = new JavaRemoveEntitiesTranslator(); // var addExperienceOrbTranslator = new JavaAddExperienceOrbTranslator();
// var removeEntitiesTranslator = new JavaRemoveEntitiesTranslator();
// Entity#teamIdentifier used to throw because it returned uuid.toString where uuid could be null. //
// this would result in both EntityCache#spawnEntity and EntityCache#removeEntity throwing an exception, // // Entity#teamIdentifier used to throw because it returned uuid.toString where uuid could be null.
// because the entity would be registered and deregistered to the scoreboard. // // this would result in both EntityCache#spawnEntity and EntityCache#removeEntity throwing an exception,
assertDoesNotThrow(() -> { // // because the entity would be registered and deregistered to the scoreboard.
context.translate(addExperienceOrbTranslator, new ClientboundAddExperienceOrbPacket(2, 0, 0, 0, 1)); // assertDoesNotThrow(() -> {
// context.translate(addExperienceOrbTranslator, new ClientboundAddExperienceOrbPacket(2, 0, 0, 0, 1));
String displayName = context.mockOrSpy(EntityCache.class).getEntityByJavaId(2).getDisplayName(); //
assertEquals("entity.minecraft.experience_orb", displayName); // String displayName = context.mockOrSpy(EntityCache.class).getEntityByJavaId(2).getDisplayName();
// assertEquals("entity.minecraft.experience_orb", displayName);
context.translate(removeEntitiesTranslator, new ClientboundRemoveEntitiesPacket(new int[]{2})); //
}); // context.translate(removeEntitiesTranslator, new ClientboundRemoveEntitiesPacket(new int[] { 2 }));
// });
// we know that spawning and removing the entity should be fine //
assertNextPacketType(context, AddEntityPacket.class); // // we know that spawning and removing the entity should be fine
assertNextPacketType(context, RemoveEntityPacket.class); // assertNextPacketType(context, AddEntityPacket.class);
}); // assertNextPacketType(context, RemoveEntityPacket.class);
} // });
// }
/** /**
* Test for <a href="https://github.com/GeyserMC/Geyser/issues/5078">#5078</a> * Test for <a href="https://github.com/GeyserMC/Geyser/issues/5078">#5078</a>
@@ -270,76 +250,4 @@ public class ScoreboardIssueTests {
}); });
}); });
} }
/**
* Test for <a href="https://github.com/GeyserMC/Geyser/issues/5353">#5353</a>.
* It follows a code snippet provided in <a href="https://github.com/GeyserMC/Geyser/pull/5415">the PR description</a>.
*/
@Test
void prefixNotShowing() {
mockContextScoreboard(context -> {
var setObjectiveTranslator = new JavaSetObjectiveTranslator();
var setDisplayObjectiveTranslator = new JavaSetDisplayObjectiveTranslator();
var setPlayerTeamTranslator = new JavaSetPlayerTeamTranslator();
var setScoreTranslator = new JavaSetScoreTranslator();
context.translate(
setObjectiveTranslator,
new ClientboundSetObjectivePacket(
"sb-0",
ObjectiveAction.ADD,
Component.text("Test Scoreboard"),
ScoreType.INTEGER,
null
)
);
assertNoNextPacket(context);
context.translate(
setDisplayObjectiveTranslator,
new ClientboundSetDisplayObjectivePacket(ScoreboardPosition.SIDEBAR, "sb-0")
);
assertNextPacket(context, () -> {
var packet = new SetDisplayObjectivePacket();
packet.setObjectiveId("0");
packet.setDisplayName("Test Scoreboard");
packet.setCriteria("dummy");
packet.setDisplaySlot("sidebar");
packet.setSortOrder(1);
return packet;
});
context.translate(
setPlayerTeamTranslator,
new ClientboundSetPlayerTeamPacket(
"sbt-1",
Component.text("displaynametest"),
Component.text("§aScore: 10"),
Component.empty(),
false,
false,
NameTagVisibility.NEVER,
CollisionRule.NEVER,
TeamColor.DARK_GREEN,
new String[]{"§0"})
);
assertNoNextPacket(context);
context.translate(
setScoreTranslator,
new ClientboundSetScorePacket(
"§0",
"sb-0",
10
).withDisplay(Component.empty())
);
assertNextPacket(context, () -> {
var packet = new SetScorePacket();
packet.setAction(SetScorePacket.Action.SET);
packet.setInfos(List.of(new ScoreInfo(1, "0", 10, "§2§aScore: 10§r§2§r§2")));
return packet;
});
assertNoNextPacket(context);
});
}
} }

View File

@@ -15,7 +15,7 @@ protocol-common = "3.0.0.Beta6-20250324.162731-5"
protocol-codec = "3.0.0.Beta6-20250324.162731-5" protocol-codec = "3.0.0.Beta6-20250324.162731-5"
raknet = "1.0.0.CR3-20250218.160705-18" raknet = "1.0.0.CR3-20250218.160705-18"
minecraftauth = "4.1.1" minecraftauth = "4.1.1"
mcprotocollib = "1.21.4-20250311.232133-24" mcprotocollib = "1.21.5-SNAPSHOT"
adventure = "4.14.0" adventure = "4.14.0"
adventure-platform = "4.3.0" adventure-platform = "4.3.0"
junit = "5.9.2" junit = "5.9.2"