3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-12-27 08:30:12 +01:00
Dieser Commit ist enthalten in:
RednedEpic 2022-10-29 22:02:11 -05:00
Ursprung 18e7db8c30
Commit a133308f51
98 geänderte Dateien mit 548 neuen und 401 gelöschten Zeilen

Datei anzeigen

@ -311,7 +311,7 @@ public class GeyserImpl implements GeyserApi {
try { try {
this.geyserServer = new GeyserServer(this, bedrockThreadCount); this.geyserServer = new GeyserServer(this, bedrockThreadCount);
this.geyserServer.bind(new InetSocketAddress(config.getBedrock().address(), config.getBedrock().port())) this.geyserServer.bind(new InetSocketAddress(config.getBedrock().address(), config.getBedrock().port()))
.syncUninterruptibly(); .awaitUninterruptibly();
logger.info(GeyserLocale.getLocaleStringLog("geyser.core.start", config.getBedrock().address(), logger.info(GeyserLocale.getLocaleStringLog("geyser.core.start", config.getBedrock().address(),
String.valueOf(config.getBedrock().port()))); String.valueOf(config.getBedrock().port())));

Datei anzeigen

@ -25,7 +25,7 @@
package org.geysermc.geyser.command.defaults; package org.geysermc.geyser.command.defaults;
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacketCodec; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommand;
@ -54,7 +54,7 @@ public class VersionCommand extends GeyserCommand {
@Override @Override
public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) { public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
String bedrockVersions; String bedrockVersions;
List<BedrockPacketCodec> supportedCodecs = GameProtocol.SUPPORTED_BEDROCK_CODECS; List<BedrockCodec> supportedCodecs = GameProtocol.SUPPORTED_BEDROCK_CODECS;
if (supportedCodecs.size() > 1) { if (supportedCodecs.size() > 1) {
bedrockVersions = supportedCodecs.get(0).getMinecraftVersion() + " - " + supportedCodecs.get(supportedCodecs.size() - 1).getMinecraftVersion(); bedrockVersions = supportedCodecs.get(0).getMinecraftVersion() + " - " + supportedCodecs.get(supportedCodecs.size() - 1).getMinecraftVersion();
} else { } else {

Datei anzeigen

@ -31,11 +31,11 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.hash.Hashing; import com.google.common.hash.Hashing;
import com.google.common.io.ByteSource; import com.google.common.io.ByteSource;
import com.google.common.io.Files; import com.google.common.io.Files;
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacketCodec;
import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.geysermc.floodgate.util.DeviceOs; import org.geysermc.floodgate.util.DeviceOs;
import org.geysermc.floodgate.util.FloodgateInfoHolder; import org.geysermc.floodgate.util.FloodgateInfoHolder;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
@ -57,7 +57,12 @@ import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Getter @Getter
@ -219,8 +224,8 @@ public class DumpInfo {
private final int javaProtocol; private final int javaProtocol;
MCInfo() { MCInfo() {
this.bedrockVersions = GameProtocol.SUPPORTED_BEDROCK_CODECS.stream().map(BedrockPacketCodec::getMinecraftVersion).toList(); this.bedrockVersions = GameProtocol.SUPPORTED_BEDROCK_CODECS.stream().map(BedrockCodec::getMinecraftVersion).toList();
this.bedrockProtocols = GameProtocol.SUPPORTED_BEDROCK_CODECS.stream().map(BedrockPacketCodec::getProtocolVersion).toList(); this.bedrockProtocols = GameProtocol.SUPPORTED_BEDROCK_CODECS.stream().map(BedrockCodec::getProtocolVersion).toList();
this.defaultBedrockProtocol = GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion(); this.defaultBedrockProtocol = GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion();
this.javaVersions = GameProtocol.getJavaVersions(); this.javaVersions = GameProtocol.getJavaVersions();
this.javaProtocol = GameProtocol.getJavaProtocolVersion(); this.javaProtocol = GameProtocol.getJavaProtocolVersion();

Datei anzeigen

@ -204,11 +204,11 @@ public final class EntityDefinitions {
.type(EntityType.BOAT) .type(EntityType.BOAT)
.height(0.6f).width(1.6f) .height(0.6f).width(1.6f)
.offset(0.35f) .offset(0.35f)
.addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityDataTypes.HURT_TIME, entityMetadata.getValue())) // Time since last hit .addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityDataTypes.HURT_TICKS, entityMetadata.getValue())) // Time since last hit
.addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityDataTypes.HURT_DIRECTION, entityMetadata.getValue())) // Rocking direction .addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityDataTypes.HURT_DIRECTION, entityMetadata.getValue())) // Rocking direction
.addTranslator(MetadataType.FLOAT, (boatEntity, entityMetadata) -> .addTranslator(MetadataType.FLOAT, (boatEntity, entityMetadata) ->
// 'Health' in Bedrock, damage taken in Java - it makes motion in Bedrock // 'Health' in Bedrock, damage taken in Java - it makes motion in Bedrock
boatEntity.getDirtyMetadata().put(EntityDataTypes.HEALTH, 40 - ((int) ((FloatEntityMetadata) entityMetadata).getPrimitiveValue()))) boatEntity.getDirtyMetadata().put(EntityDataTypes.STRUCTURAL_INTEGRITY, 40 - ((int) ((FloatEntityMetadata) entityMetadata).getPrimitiveValue())))
.addTranslator(MetadataType.INT, BoatEntity::setVariant) .addTranslator(MetadataType.INT, BoatEntity::setVariant)
.addTranslator(MetadataType.BOOLEAN, BoatEntity::setPaddlingLeft) .addTranslator(MetadataType.BOOLEAN, BoatEntity::setPaddlingLeft)
.addTranslator(MetadataType.BOOLEAN, BoatEntity::setPaddlingRight) .addTranslator(MetadataType.BOOLEAN, BoatEntity::setPaddlingRight)
@ -367,11 +367,11 @@ public final class EntityDefinitions {
.type(EntityType.MINECART) .type(EntityType.MINECART)
.height(0.7f).width(0.98f) .height(0.7f).width(0.98f)
.offset(0.35f) .offset(0.35f)
.addTranslator(MetadataType.INT, (minecartEntity, entityMetadata) -> minecartEntity.getDirtyMetadata().put(EntityDataTypes.HEALTH, entityMetadata.getValue())) .addTranslator(MetadataType.INT, (minecartEntity, entityMetadata) -> minecartEntity.getDirtyMetadata().put(EntityDataTypes.STRUCTURAL_INTEGRITY, entityMetadata.getValue()))
.addTranslator(MetadataType.INT, (minecartEntity, entityMetadata) -> minecartEntity.getDirtyMetadata().put(EntityDataTypes.HURT_DIRECTION, entityMetadata.getValue())) // Direction in which the minecart is shaking .addTranslator(MetadataType.INT, (minecartEntity, entityMetadata) -> minecartEntity.getDirtyMetadata().put(EntityDataTypes.HURT_DIRECTION, entityMetadata.getValue())) // Direction in which the minecart is shaking
.addTranslator(MetadataType.FLOAT, (minecartEntity, entityMetadata) -> .addTranslator(MetadataType.FLOAT, (minecartEntity, entityMetadata) ->
// Power in Java, time in Bedrock // Power in Java, hurt ticks in Bedrock
minecartEntity.getDirtyMetadata().put(EntityDataTypes.HURT_TIME, Math.min((int) ((FloatEntityMetadata) entityMetadata).getPrimitiveValue(), 15))) minecartEntity.getDirtyMetadata().put(EntityDataTypes.HURT_TICKS, Math.min((int) ((FloatEntityMetadata) entityMetadata).getPrimitiveValue(), 15)))
.addTranslator(MetadataType.INT, MinecartEntity::setCustomBlock) .addTranslator(MetadataType.INT, MinecartEntity::setCustomBlock)
.addTranslator(MetadataType.INT, MinecartEntity::setCustomBlockOffset) .addTranslator(MetadataType.INT, MinecartEntity::setCustomBlockOffset)
.addTranslator(MetadataType.BOOLEAN, MinecartEntity::setShowCustomBlock) .addTranslator(MetadataType.BOOLEAN, MinecartEntity::setShowCustomBlock)
@ -381,7 +381,7 @@ public final class EntityDefinitions {
.build(); .build();
COMMAND_BLOCK_MINECART = EntityDefinition.inherited(CommandBlockMinecartEntity::new, MINECART) COMMAND_BLOCK_MINECART = EntityDefinition.inherited(CommandBlockMinecartEntity::new, MINECART)
.type(EntityType.COMMAND_BLOCK_MINECART) .type(EntityType.COMMAND_BLOCK_MINECART)
.addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.COMMAND_BLOCK_COMMAND, entityMetadata.getValue())) .addTranslator(MetadataType.STRING, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.COMMAND_BLOCK_NAME, entityMetadata.getValue()))
.addTranslator(MetadataType.CHAT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage(entityMetadata.getValue()))) .addTranslator(MetadataType.CHAT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage(entityMetadata.getValue())))
.build(); .build();
FURNACE_MINECART = EntityDefinition.inherited(FurnaceMinecartEntity::new, MINECART) FURNACE_MINECART = EntityDefinition.inherited(FurnaceMinecartEntity::new, MINECART)
@ -415,7 +415,7 @@ public final class EntityDefinitions {
.addTranslator(MetadataType.INT, .addTranslator(MetadataType.INT,
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue())) (livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue()))
.addTranslator(MetadataType.BOOLEAN, .addTranslator(MetadataType.BOOLEAN,
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_AMBIENT, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0))) (livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_AMBIENCE, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0)))
.addTranslator(null) // Arrow count .addTranslator(null) // Arrow count
.addTranslator(null) // Stinger count .addTranslator(null) // Stinger count
.addTranslator(MetadataType.OPTIONAL_POSITION, LivingEntity::setBedPosition) .addTranslator(MetadataType.OPTIONAL_POSITION, LivingEntity::setBedPosition)

Datei anzeigen

@ -29,10 +29,12 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadat
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.level.particle.Particle; import com.github.steveice10.mc.protocol.data.game.level.particle.Particle;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.registry.type.ParticleMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID; import java.util.UUID;
@ -61,14 +63,12 @@ public class AreaEffectCloudEntity extends Entity {
// Anything less than 0.5 will cause the cloud to despawn // Anything less than 0.5 will cause the cloud to despawn
float value = Math.max(entityMetadata.getPrimitiveValue(), 0.5f); float value = Math.max(entityMetadata.getPrimitiveValue(), 0.5f);
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, value); dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, value);
dirtyMetadata.put(EntityDataTypes.BOUNDING_BOX_WIDTH, 2.0f * value); dirtyMetadata.put(EntityDataTypes.WIDTH, 2.0f * value);
} }
public void setParticle(EntityMetadata<Particle, ?> entityMetadata) { public void setParticle(EntityMetadata<Particle, ?> entityMetadata) {
Particle particle = entityMetadata.getValue(); Particle particle = entityMetadata.getValue();
int particleId = Registries.PARTICLES.map(particle.getType(), mapping -> mapping.getParticleId(this.session)).orElse(-1); Registries.PARTICLES.map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type ->
if (particleId != -1) { dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE, type));
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE_ID, particleId);
}
} }
} }

Datei anzeigen

@ -60,7 +60,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
customBlock = entityMetadata.getPrimitiveValue(); customBlock = entityMetadata.getPrimitiveValue();
if (showCustomBlock) { if (showCustomBlock) {
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlockId(customBlock)); dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(customBlock));
} }
} }
@ -77,7 +77,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
public void setShowCustomBlock(BooleanEntityMetadata entityMetadata) { public void setShowCustomBlock(BooleanEntityMetadata entityMetadata) {
if (entityMetadata.getPrimitiveValue()) { if (entityMetadata.getPrimitiveValue()) {
showCustomBlock = true; showCustomBlock = true;
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlockId(customBlock)); dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(customBlock));
dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, customBlockOffset); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, customBlockOffset);
} else { } else {
showCustomBlock = false; showCustomBlock = false;

Datei anzeigen

@ -54,9 +54,9 @@ public class EnderCrystalEntity extends Entity {
// Usually performed client-side on Bedrock except for Ender Dragon respawn event // Usually performed client-side on Bedrock except for Ender Dragon respawn event
Optional<Vector3i> optionalPos = entityMetadata.getValue(); Optional<Vector3i> optionalPos = entityMetadata.getValue();
if (optionalPos.isPresent()) { if (optionalPos.isPresent()) {
dirtyMetadata.put(EntityDataTypes.BLOCK_TARGET, optionalPos.get()); dirtyMetadata.put(EntityDataTypes.BLOCK_TARGET_POS, optionalPos.get());
} else { } else {
dirtyMetadata.put(EntityDataTypes.BLOCK_TARGET, Vector3i.ZERO); dirtyMetadata.put(EntityDataTypes.BLOCK_TARGET_POS, Vector3i.ZERO);
} }
} }
} }

Datei anzeigen

@ -42,14 +42,14 @@ public class EvokerFangsEntity extends Entity implements Tickable {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
// As of 1.18.2 Bedrock, this line is required for the entity to be visible // As of 1.18.2 Bedrock, this line is required for the entity to be visible
// 22 is the starting number on Java Edition // 22 is the starting number on Java Edition
dirtyMetadata.put(EntityDataTypes.LIMITED_LIFE, this.limitedLife); dirtyMetadata.put(EntityDataTypes.DATA_LIFETIME_TICKS, this.limitedLife);
} }
@Override @Override
public void tick() { public void tick() {
if (attackStarted) { if (attackStarted) {
if (--this.limitedLife > 0 && this.limitedLife % 2 == 0) { // Matches Bedrock behavior if (--this.limitedLife > 0 && this.limitedLife % 2 == 0) { // Matches Bedrock behavior
dirtyMetadata.put(EntityDataTypes.LIMITED_LIFE, this.limitedLife); dirtyMetadata.put(EntityDataTypes.DATA_LIFETIME_TICKS, this.limitedLife);
updateBedrockMetadata(); updateBedrockMetadata();
} }
} }

Datei anzeigen

@ -35,6 +35,6 @@ public class ExpOrbEntity extends Entity {
public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) { public ExpOrbEntity(GeyserSession session, int amount, int entityId, long geyserId, Vector3f position) {
super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0); super(session, entityId, geyserId, null, EntityDefinitions.EXPERIENCE_ORB, position, Vector3f.ZERO, 0, 0, 0);
this.dirtyMetadata.put(EntityDataTypes.EXPERIENCE_VALUE, amount); this.dirtyMetadata.put(EntityDataTypes.TRADE_EXPERIENCE, amount);
} }
} }

Datei anzeigen

@ -51,7 +51,7 @@ public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity {
@Override @Override
public void updateDefaultBlockMetadata() { public void updateDefaultBlockMetadata() {
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlockId(hasFuel ? BlockStateValues.JAVA_FURNACE_LIT_ID : BlockStateValues.JAVA_FURNACE_ID)); dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(hasFuel ? BlockStateValues.JAVA_FURNACE_LIT_ID : BlockStateValues.JAVA_FURNACE_ID));
dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6);
} }

Datei anzeigen

@ -38,6 +38,7 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag;
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.AttributeData; import org.cloudburstmc.protocol.bedrock.data.AttributeData;
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
@ -88,7 +89,7 @@ public class LivingEntity extends Entity {
protected void initializeMetadata() { protected void initializeMetadata() {
super.initializeMetadata(); super.initializeMetadata();
// Matches Bedrock behavior; is always set to this // Matches Bedrock behavior; is always set to this
dirtyMetadata.put(EntityDataTypes.HEALTH, 1); dirtyMetadata.put(EntityDataTypes.STRUCTURAL_INTEGRITY, 1);
} }
public void setLivingEntityFlags(ByteEntityMetadata entityMetadata) { public void setLivingEntityFlags(ByteEntityMetadata entityMetadata) {
@ -143,9 +144,9 @@ public class LivingEntity extends Entity {
protected boolean hasShield(boolean offhand, ItemMapping shieldMapping) { protected boolean hasShield(boolean offhand, ItemMapping shieldMapping) {
if (offhand) { if (offhand) {
return offHand.getId() == shieldMapping.getBedrockDefinition(); return offHand.getDefinition().equals(shieldMapping.getBedrockDefinition());
} else { } else {
return hand.getId() == shieldMapping.getBedrockDefinition(); return hand.getDefinition().equals(shieldMapping.getBedrockDefinition());
} }
} }
@ -189,7 +190,7 @@ public class LivingEntity extends Entity {
@Override @Override
public InteractionResult interact(Hand hand) { public InteractionResult interact(Hand hand) {
GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(hand); GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(hand);
if (itemStack.getJavaId() == session.getItemMappings().getStoredItems().nameTag()) { if (itemStack.getJavaId() == session.getItemMappings().getStoredItems().nameTag().getJavaId()) {
InteractionResult result = checkInteractWithNameTag(itemStack); InteractionResult result = checkInteractWithNameTag(itemStack);
if (result.consumesAction()) { if (result.consumesAction()) {
return result; return result;
@ -219,10 +220,10 @@ public class LivingEntity extends Entity {
// If an entity has a banner on them, it will be in the helmet slot in Java but the chestplate spot in Bedrock // If an entity has a banner on them, it will be in the helmet slot in Java but the chestplate spot in Bedrock
// But don't overwrite the chestplate if it isn't empty // But don't overwrite the chestplate if it isn't empty
ItemMapping banner = session.getItemMappings().getStoredItems().banner(); ItemMapping banner = session.getItemMappings().getStoredItems().banner();
if (chestplate.getId() == ItemData.AIR.getId() && helmet.getId() == banner.getBedrockDefinition()) { if (ItemDefinition.AIR.equals(chestplate.getDefinition()) && helmet.getDefinition().equals(banner.getBedrockDefinition())) {
chestplate = this.helmet; chestplate = this.helmet;
helmet = ItemData.AIR; helmet = ItemData.AIR;
} else if (chestplate.getId() == banner.getBedrockDefinition()) { } else if (chestplate.getDefinition().equals(banner.getBedrockDefinition())) {
// Prevent chestplate banners from showing erroneously // Prevent chestplate banners from showing erroneously
chestplate = ItemData.AIR; chestplate = ItemData.AIR;
} }

Datei anzeigen

@ -45,7 +45,7 @@ public class MinecartEntity extends Entity {
} }
public void setCustomBlock(IntEntityMetadata entityMetadata) { public void setCustomBlock(IntEntityMetadata entityMetadata) {
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlockId(entityMetadata.getPrimitiveValue())); dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(entityMetadata.getPrimitiveValue()));
} }
public void setCustomBlockOffset(IntEntityMetadata entityMetadata) { public void setCustomBlockOffset(IntEntityMetadata entityMetadata) {

Datei anzeigen

@ -41,7 +41,7 @@ public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity {
@Override @Override
public void updateDefaultBlockMetadata() { public void updateDefaultBlockMetadata() {
dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlockId(BlockStateValues.JAVA_SPAWNER_ID)); dirtyMetadata.put(EntityDataTypes.DISPLAY_BLOCK_STATE, session.getBlockMappings().getBedrockBlock(BlockStateValues.JAVA_SPAWNER_ID));
dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6); dirtyMetadata.put(EntityDataTypes.DISPLAY_OFFSET, 6);
} }
} }

Datei anzeigen

@ -27,7 +27,7 @@ package org.geysermc.geyser.entity.type;
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket; import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket;
@ -174,7 +174,7 @@ public class ThrowableEntity extends Entity implements Tickable {
public boolean despawnEntity() { public boolean despawnEntity() {
if (definition.entityType() == EntityType.ENDER_PEARL) { if (definition.entityType() == EntityType.ENDER_PEARL) {
LevelEventPacket particlePacket = new LevelEventPacket(); LevelEventPacket particlePacket = new LevelEventPacket();
particlePacket.setType(LevelEventType.PARTICLE_TELEPORT); particlePacket.setType(LevelEvent.PARTICLE_TELEPORT);
particlePacket.setPosition(position); particlePacket.setPosition(position);
session.sendUpstreamPacket(particlePacket); session.sendUpstreamPacket(particlePacket);
} }

Datei anzeigen

@ -52,7 +52,7 @@ public class ThrownPotionEntity extends ThrowableItemEntity {
public void setItem(EntityMetadata<ItemStack, ?> entityMetadata) { public void setItem(EntityMetadata<ItemStack, ?> entityMetadata) {
ItemStack itemStack = entityMetadata.getValue(); ItemStack itemStack = entityMetadata.getValue();
if (itemStack == null) { if (itemStack == null) {
dirtyMetadata.put(EntityDataTypes.POTION_AUX_VALUE, 0); dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
setFlag(EntityFlag.ENCHANTED, false); setFlag(EntityFlag.ENCHANTED, false);
setFlag(EntityFlag.LINGERING, false); setFlag(EntityFlag.LINGERING, false);
} else { } else {
@ -62,10 +62,10 @@ public class ThrownPotionEntity extends ThrowableItemEntity {
if (potionTag instanceof StringTag) { if (potionTag instanceof StringTag) {
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
if (potion != null) { if (potion != null) {
dirtyMetadata.put(EntityDataTypes.POTION_AUX_VALUE, potion.getBedrockId()); dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, potion.getBedrockId());
setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion)); setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion));
} else { } else {
dirtyMetadata.put(EntityDataTypes.POTION_AUX_VALUE, 0); dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionTag.getValue()); GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionTag.getValue());
} }
} }

Datei anzeigen

@ -87,6 +87,6 @@ public class AllayEntity extends MobEntity {
} }
private boolean isDuplicationItem(GeyserItemStack itemStack) { private boolean isDuplicationItem(GeyserItemStack itemStack) {
return itemStack.getJavaId() == session.getItemMappings().getStoredItems().amethystShard(); return itemStack.getJavaId() == session.getItemMappings().getStoredItems().amethystShard().getJavaId();
} }
} }

Datei anzeigen

@ -29,12 +29,13 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadat
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import lombok.Getter;
import net.kyori.adventure.text.Component;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import lombok.Getter;
import net.kyori.adventure.text.Component;
import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.entity.type.LivingEntity;
@ -205,7 +206,7 @@ public class ArmorStandEntity extends LivingEntity {
* @param negativeZToggle the flag to set true if the Z value of rotation is negative * @param negativeZToggle the flag to set true if the Z value of rotation is negative
* @param rotation the Java rotation value * @param rotation the Java rotation value
*/ */
private void onRotationUpdate(EntityData dataLeech, EntityFlag negativeXToggle, EntityFlag negativeYToggle, EntityFlag negativeZToggle, Vector3f rotation) { private void onRotationUpdate(EntityDataType dataLeech, EntityFlag negativeXToggle, EntityFlag negativeYToggle, EntityFlag negativeZToggle, Vector3f rotation) {
// Indicate that rotation should be checked // Indicate that rotation should be checked
setFlag(EntityFlag.BRIBED, true); setFlag(EntityFlag.BRIBED, true);
@ -246,7 +247,7 @@ public class ArmorStandEntity extends LivingEntity {
@Override @Override
public InteractionResult interactAt(Hand hand) { public InteractionResult interactAt(Hand hand) {
if (!isMarker && session.getPlayerInventory().getItemInHand(hand).getJavaId() != session.getItemMappings().getStoredItems().nameTag()) { if (!isMarker && session.getPlayerInventory().getItemInHand(hand).getJavaId() != session.getItemMappings().getStoredItems().nameTag().getJavaId()) {
// Java Edition returns SUCCESS if in spectator mode, but this is overrided with an earlier check on the client // Java Edition returns SUCCESS if in spectator mode, but this is overrided with an earlier check on the client
return InteractionResult.CONSUME; return InteractionResult.CONSUME;
} else { } else {
@ -341,16 +342,16 @@ public class ArmorStandEntity extends LivingEntity {
secondEntity.isSmall = isSmall; secondEntity.isSmall = isSmall;
secondEntity.isMarker = isMarker; secondEntity.isMarker = isMarker;
secondEntity.positionRequiresOffset = true; // Offset should always be applied secondEntity.positionRequiresOffset = true; // Offset should always be applied
secondEntity.getDirtyMetadata().put(EntityDataTypes.NAMETAG, nametag); secondEntity.getDirtyMetadata().put(EntityDataTypes.NAME, nametag);
secondEntity.getDirtyMetadata().put(EntityDataTypes.NAMETAG_ALWAYS_SHOW, isNameTagVisible ? (byte) 1 : (byte) 0); secondEntity.getDirtyMetadata().put(EntityDataTypes.NAMETAG_ALWAYS_SHOW, isNameTagVisible ? (byte) 1 : (byte) 0);
secondEntity.flags.merge(this.flags); secondEntity.flags.addAll(this.flags);
// Guarantee this copy is NOT invisible // Guarantee this copy is NOT invisible
secondEntity.setFlag(EntityFlag.INVISIBLE, false); secondEntity.setFlag(EntityFlag.INVISIBLE, false);
// Scale to 0 to show nametag // Scale to 0 to show nametag
secondEntity.getDirtyMetadata().put(EntityDataTypes.SCALE, 0.0f); secondEntity.getDirtyMetadata().put(EntityDataTypes.SCALE, 0.0f);
// No bounding box as we don't want to interact with this entity // No bounding box as we don't want to interact with this entity
secondEntity.getDirtyMetadata().put(EntityDataTypes.BOUNDING_BOX_WIDTH, 0.0f); secondEntity.getDirtyMetadata().put(EntityDataTypes.WIDTH, 0.0f);
secondEntity.getDirtyMetadata().put(EntityDataTypes.BOUNDING_BOX_HEIGHT, 0.0f); secondEntity.getDirtyMetadata().put(EntityDataTypes.HEIGHT, 0.0f);
if (!secondEntity.valid) { // Spawn the entity once if (!secondEntity.valid) { // Spawn the entity once
secondEntity.spawnEntity(); secondEntity.spawnEntity();
} }

Datei anzeigen

@ -53,7 +53,7 @@ public class IronGolemEntity extends GolemEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().ironIngot()) { if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().ironIngot().getJavaId()) {
if (health < maxHealth) { if (health < maxHealth) {
// Healing the iron golem // Healing the iron golem
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;

Datei anzeigen

@ -67,7 +67,7 @@ public class MobEntity extends LivingEntity {
public void setLeashHolderBedrockId(long bedrockId) { public void setLeashHolderBedrockId(long bedrockId) {
this.leashHolderBedrockId = bedrockId; this.leashHolderBedrockId = bedrockId;
dirtyMetadata.put(EntityDataTypes.LEASH_HOLDER_EID, bedrockId); dirtyMetadata.put(EntityDataTypes.LEASH_HOLDER, bedrockId);
} }
@Override @Override
@ -80,10 +80,10 @@ public class MobEntity extends LivingEntity {
} else { } else {
GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(hand); GeyserItemStack itemStack = session.getPlayerInventory().getItemInHand(hand);
StoredItemMappings storedItems = session.getItemMappings().getStoredItems(); StoredItemMappings storedItems = session.getItemMappings().getStoredItems();
if (itemStack.getJavaId() == storedItems.lead() && canBeLeashed()) { if (itemStack.getJavaId() == storedItems.lead().getJavaId() && canBeLeashed()) {
// We shall leash // We shall leash
return InteractiveTag.LEASH; return InteractiveTag.LEASH;
} else if (itemStack.getJavaId() == storedItems.nameTag()) { } else if (itemStack.getJavaId() == storedItems.nameTag().getJavaId()) {
InteractionResult result = checkInteractWithNameTag(itemStack); InteractionResult result = checkInteractWithNameTag(itemStack);
if (result.consumesAction()) { if (result.consumesAction()) {
return InteractiveTag.NAME; return InteractiveTag.NAME;
@ -117,10 +117,10 @@ public class MobEntity extends LivingEntity {
private InteractionResult checkPriorityInteractions(GeyserItemStack itemInHand) { private InteractionResult checkPriorityInteractions(GeyserItemStack itemInHand) {
StoredItemMappings storedItems = session.getItemMappings().getStoredItems(); StoredItemMappings storedItems = session.getItemMappings().getStoredItems();
if (itemInHand.getJavaId() == storedItems.lead() && canBeLeashed()) { if (itemInHand.getJavaId() == storedItems.lead().getJavaId() && canBeLeashed()) {
// We shall leash // We shall leash
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} else if (itemInHand.getJavaId() == storedItems.nameTag()) { } else if (itemInHand.getJavaId() == storedItems.nameTag().getJavaId()) {
InteractionResult result = checkInteractWithNameTag(itemInHand); InteractionResult result = checkInteractWithNameTag(itemInHand);
if (result.consumesAction()) { if (result.consumesAction()) {
return result; return result;

Datei anzeigen

@ -53,7 +53,7 @@ public class SnowGolemEntity extends GolemEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (session.getItemMappings().getStoredItems().shears() == itemInHand.getJavaId() && isAlive() && !getFlag(EntityFlag.SHEARED)) { if (session.getItemMappings().getStoredItems().shears().getJavaId() == itemInHand.getJavaId() && isAlive() && !getFlag(EntityFlag.SHEARED)) {
// Shearing the snow golem // Shearing the snow golem
return InteractiveTag.SHEAR; return InteractiveTag.SHEAR;
} }
@ -63,7 +63,7 @@ public class SnowGolemEntity extends GolemEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (session.getItemMappings().getStoredItems().shears() == itemInHand.getJavaId() && isAlive() && !getFlag(EntityFlag.SHEARED)) { if (session.getItemMappings().getStoredItems().shears().getJavaId() == itemInHand.getJavaId() && isAlive() && !getFlag(EntityFlag.SHEARED)) {
// Shearing the snow golem // Shearing the snow golem
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }

Datei anzeigen

@ -61,6 +61,6 @@ public class TadpoleEntity extends AbstractFishEntity {
} }
private boolean isFood(GeyserItemStack itemStack) { private boolean isFood(GeyserItemStack itemStack) {
return itemStack.getJavaId() == session.getItemMappings().getStoredItems().slimeBall(); return itemStack.getJavaId() == session.getItemMappings().getStoredItems().slimeBall().getJavaId();
} }
} }

Datei anzeigen

@ -76,6 +76,6 @@ public class FrogEntity extends AnimalEntity {
@Override @Override
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) { public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return mapping.getJavaId() == session.getItemMappings().getStoredItems().slimeBall(); return mapping.getJavaId() == session.getItemMappings().getStoredItems().slimeBall().getJavaId();
} }
} }

Datei anzeigen

@ -56,10 +56,10 @@ public class MooshroomEntity extends AnimalEntity {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
StoredItemMappings storedItems = session.getItemMappings().getStoredItems(); StoredItemMappings storedItems = session.getItemMappings().getStoredItems();
if (!isBaby()) { if (!isBaby()) {
if (itemInHand.getJavaId() == storedItems.bowl()) { if (itemInHand.getJavaId() == storedItems.bowl().getJavaId()) {
// Stew // Stew
return InteractiveTag.MOOSHROOM_MILK_STEW; return InteractiveTag.MOOSHROOM_MILK_STEW;
} else if (isAlive() && itemInHand.getJavaId() == storedItems.shears()) { } else if (isAlive() && itemInHand.getJavaId() == storedItems.shears().getJavaId()) {
// Shear items // Shear items
return InteractiveTag.MOOSHROOM_SHEAR; return InteractiveTag.MOOSHROOM_SHEAR;
} }
@ -72,10 +72,10 @@ public class MooshroomEntity extends AnimalEntity {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
StoredItemMappings storedItems = session.getItemMappings().getStoredItems(); StoredItemMappings storedItems = session.getItemMappings().getStoredItems();
boolean isBaby = isBaby(); boolean isBaby = isBaby();
if (!isBaby && itemInHand.getJavaId() == storedItems.bowl()) { if (!isBaby && itemInHand.getJavaId() == storedItems.bowl().getJavaId()) {
// Stew // Stew
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} else if (!isBaby && isAlive() && itemInHand.getJavaId() == storedItems.shears()) { } else if (!isBaby && isAlive() && itemInHand.getJavaId() == storedItems.shears().getJavaId()) {
// Shear items // Shear items
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} else if (isBrown && session.getTagCache().isSmallFlower(itemInHand) && itemInHand.getMapping(session).isHasSuspiciousStewEffect()) { } else if (isBrown && session.getTagCache().isSmallFlower(itemInHand) && itemInHand.getMapping(session).isHasSuspiciousStewEffect()) {

Datei anzeigen

@ -61,7 +61,7 @@ public class PandaEntity extends AnimalEntity {
EntityEventPacket packet = new EntityEventPacket(); EntityEventPacket packet = new EntityEventPacket();
packet.setRuntimeEntityId(geyserId); packet.setRuntimeEntityId(geyserId);
packet.setType(EntityEventType.EATING_ITEM); packet.setType(EntityEventType.EATING_ITEM);
packet.setData(session.getItemMappings().getStoredItems().bamboo().getBedrockDefinition() << 16); packet.setData(session.getItemMappings().getStoredItems().bamboo().getBedrockDefinition().getRuntimeId() << 16);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
} }
} }

Datei anzeigen

@ -42,7 +42,7 @@ public class PufferFishEntity extends AbstractFishEntity {
public void setPufferfishSize(IntEntityMetadata entityMetadata) { public void setPufferfishSize(IntEntityMetadata entityMetadata) {
int puffsize = entityMetadata.getPrimitiveValue(); int puffsize = entityMetadata.getPrimitiveValue();
dirtyMetadata.put(EntityDataTypes.PUFFERFISH_SIZE, (byte) puffsize); dirtyMetadata.put(EntityDataTypes.PUFFED_STATE, (byte) puffsize);
dirtyMetadata.put(EntityDataTypes.VARIANT, puffsize); dirtyMetadata.put(EntityDataTypes.VARIANT, puffsize);
} }
} }

Datei anzeigen

@ -57,7 +57,7 @@ public class SheepEntity extends AnimalEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().shears()) { if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().shears().getJavaId()) {
return InteractiveTag.SHEAR; return InteractiveTag.SHEAR;
} else { } else {
InteractiveTag tag = super.testMobInteraction(hand, itemInHand); InteractiveTag tag = super.testMobInteraction(hand, itemInHand);
@ -76,7 +76,7 @@ public class SheepEntity extends AnimalEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().shears()) { if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().shears().getJavaId()) {
return InteractionResult.CONSUME; return InteractionResult.CONSUME;
} else { } else {
InteractionResult superResult = super.mobInteract(hand, itemInHand); InteractionResult superResult = super.mobInteract(hand, itemInHand);

Datei anzeigen

@ -165,7 +165,7 @@ public class AbstractHorseEntity extends AnimalEntity {
return InteractiveTag.ATTACH_CHEST; return InteractiveTag.ATTACH_CHEST;
} }
if (additionalTestForInventoryOpen(itemInHand) || !isBaby && !getFlag(EntityFlag.SADDLED) && itemInHand.getJavaId() == session.getItemMappings().getStoredItems().saddle()) { if (additionalTestForInventoryOpen(itemInHand) || !isBaby && !getFlag(EntityFlag.SADDLED) && itemInHand.getJavaId() == session.getItemMappings().getStoredItems().saddle().getJavaId()) {
// Will open the inventory to be saddled // Will open the inventory to be saddled
return InteractiveTag.OPEN_CONTAINER; return InteractiveTag.OPEN_CONTAINER;
} }
@ -221,7 +221,7 @@ public class AbstractHorseEntity extends AnimalEntity {
} }
// Note: yes, this code triggers for llamas too. lol (as of Java Edition 1.18.1) // Note: yes, this code triggers for llamas too. lol (as of Java Edition 1.18.1)
if (additionalTestForInventoryOpen(itemInHand) || (!isBaby && !getFlag(EntityFlag.SADDLED) && itemInHand.getJavaId() == session.getItemMappings().getStoredItems().saddle())) { if (additionalTestForInventoryOpen(itemInHand) || (!isBaby && !getFlag(EntityFlag.SADDLED) && itemInHand.getJavaId() == session.getItemMappings().getStoredItems().saddle().getJavaId())) {
// Will open the inventory to be saddled // Will open the inventory to be saddled
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
@ -260,7 +260,7 @@ public class AbstractHorseEntity extends AnimalEntity {
} else if (!passengers.isEmpty()) { } else if (!passengers.isEmpty()) {
return testHorseInteraction(hand, itemInHand); return testHorseInteraction(hand, itemInHand);
} else { } else {
if (session.getItemMappings().getStoredItems().saddle() == itemInHand.getJavaId()) { if (session.getItemMappings().getStoredItems().saddle().getJavaId() == itemInHand.getJavaId()) {
return InteractiveTag.OPEN_CONTAINER; return InteractiveTag.OPEN_CONTAINER;
} }

Datei anzeigen

@ -53,7 +53,7 @@ public class ChestedHorseEntity extends AbstractHorseEntity {
@Override @Override
protected boolean testForChest(@Nonnull GeyserItemStack itemInHand) { protected boolean testForChest(@Nonnull GeyserItemStack itemInHand) {
return itemInHand.getJavaId() == session.getItemMappings().getStoredItems().chest() && !getFlag(EntityFlag.CHESTED); return itemInHand.getJavaId() == session.getItemMappings().getStoredItems().chest().getJavaId() && !getFlag(EntityFlag.CHESTED);
} }
@Override @Override

Datei anzeigen

@ -65,7 +65,7 @@ public class CreeperEntity extends MonsterEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().flintAndSteel()) { if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().flintAndSteel().getJavaId()) {
return InteractiveTag.IGNITE_CREEPER; return InteractiveTag.IGNITE_CREEPER;
} else { } else {
return super.testMobInteraction(hand, itemInHand); return super.testMobInteraction(hand, itemInHand);
@ -75,7 +75,7 @@ public class CreeperEntity extends MonsterEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().flintAndSteel()) { if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().flintAndSteel().getJavaId()) {
// Ignite creeper // Ignite creeper
session.playSoundEvent(SoundEvent.IGNITE, position); session.playSoundEvent(SoundEvent.IGNITE, position);
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;

Datei anzeigen

@ -27,12 +27,16 @@ package org.geysermc.geyser.entity.type.living.monster;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import lombok.Data;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.ParticleType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.packet.*; import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket;
import lombok.Data; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket;
import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.entity.type.Tickable;
import org.geysermc.geyser.entity.type.living.MobEntity; import org.geysermc.geyser.entity.type.living.MobEntity;
@ -249,7 +253,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable {
Vector3f particlePos = headCenter.add(random.nextGaussian() / 2f, random.nextGaussian() / 2f, random.nextGaussian() / 2f); Vector3f particlePos = headCenter.add(random.nextGaussian() / 2f, random.nextGaussian() / 2f, random.nextGaussian() / 2f);
// This is missing velocity information // This is missing velocity information
LevelEventPacket particlePacket = new LevelEventPacket(); LevelEventPacket particlePacket = new LevelEventPacket();
particlePacket.setType(LevelEventType.PARTICLE_DRAGONS_BREATH); particlePacket.setType(ParticleType.DRAGON_BREATH);
particlePacket.setPosition(particlePos); particlePacket.setPosition(particlePos);
session.sendUpstreamPacket(particlePacket); session.sendUpstreamPacket(particlePacket);
} }
@ -277,7 +281,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable {
float zOffset = 8f * (random.nextFloat() - 0.5f); float zOffset = 8f * (random.nextFloat() - 0.5f);
Vector3f particlePos = position.add(xOffset, yOffset, zOffset); Vector3f particlePos = position.add(xOffset, yOffset, zOffset);
LevelEventPacket particlePacket = new LevelEventPacket(); LevelEventPacket particlePacket = new LevelEventPacket();
particlePacket.setType(LevelEventType.PARTICLE_EXPLOSION); particlePacket.setType(ParticleType.EXPLODE);
particlePacket.setPosition(particlePos); particlePacket.setPosition(particlePos);
session.sendUpstreamPacket(particlePacket); session.sendUpstreamPacket(particlePacket);
} }

Datei anzeigen

@ -37,8 +37,8 @@ public class EnderDragonPartEntity extends Entity {
public EnderDragonPartEntity(GeyserSession session, int entityId, long geyserId, float width, float height) { public EnderDragonPartEntity(GeyserSession session, int entityId, long geyserId, float width, float height) {
super(session, entityId, geyserId, null, EntityDefinitions.ENDER_DRAGON_PART, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0); super(session, entityId, geyserId, null, EntityDefinitions.ENDER_DRAGON_PART, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0);
dirtyMetadata.put(EntityDataTypes.BOUNDING_BOX_WIDTH, width); dirtyMetadata.put(EntityDataTypes.WIDTH, width);
dirtyMetadata.put(EntityDataTypes.BOUNDING_BOX_HEIGHT, height); dirtyMetadata.put(EntityDataTypes.HEIGHT, height);
setFlag(EntityFlag.INVISIBLE, true); setFlag(EntityFlag.INVISIBLE, true);
setFlag(EntityFlag.FIRE_IMMUNE, true); setFlag(EntityFlag.FIRE_IMMUNE, true);
} }

Datei anzeigen

@ -44,7 +44,7 @@ public class EndermanEntity extends MonsterEntity {
} }
public void setCarriedBlock(IntEntityMetadata entityMetadata) { public void setCarriedBlock(IntEntityMetadata entityMetadata) {
dirtyMetadata.put(EntityDataTypes.CARRIED_BLOCK, session.getBlockMappings().getBedrockBlockId(entityMetadata.getPrimitiveValue())); dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getBedrockBlock(entityMetadata.getPrimitiveValue()));
} }
/** /**

Datei anzeigen

@ -93,6 +93,6 @@ public class PiglinEntity extends BasePiglinEntity {
} }
private boolean canGiveGoldTo(@Nonnull GeyserItemStack itemInHand) { private boolean canGiveGoldTo(@Nonnull GeyserItemStack itemInHand) {
return !getFlag(EntityFlag.BABY) && itemInHand.getJavaId() == session.getItemMappings().getStoredItems().goldIngot() && !getFlag(EntityFlag.ADMIRING); return !getFlag(EntityFlag.BABY) && itemInHand.getJavaId() == session.getItemMappings().getStoredItems().goldIngot().getJavaId() && !getFlag(EntityFlag.ADMIRING);
} }
} }

Datei anzeigen

@ -52,7 +52,7 @@ public class ShulkerEntity extends GolemEntity {
public void setShulkerHeight(ByteEntityMetadata entityMetadata) { public void setShulkerHeight(ByteEntityMetadata entityMetadata) {
int height = entityMetadata.getPrimitiveValue(); int height = entityMetadata.getPrimitiveValue();
dirtyMetadata.put(EntityDataTypes.SHULKER_PEEK_ID, height); dirtyMetadata.put(EntityDataTypes.SHULKER_PEEK_AMOUNT, height);
} }
public void setShulkerColor(ByteEntityMetadata entityMetadata) { public void setShulkerColor(ByteEntityMetadata entityMetadata) {

Datei anzeigen

@ -69,7 +69,7 @@ public class ZombieVillagerEntity extends ZombieEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().goldenApple()) { if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().goldenApple().getJavaId()) {
return InteractiveTag.CURE; return InteractiveTag.CURE;
} else { } else {
return super.testMobInteraction(hand, itemInHand); return super.testMobInteraction(hand, itemInHand);
@ -79,7 +79,7 @@ public class ZombieVillagerEntity extends ZombieEntity {
@Nonnull @Nonnull
@Override @Override
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) { protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().goldenApple()) { if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().goldenApple().getJavaId()) {
// The client doesn't know if the entity has weakness as that's not usually sent over the network // The client doesn't know if the entity has weakness as that's not usually sent over the network
return InteractionResult.CONSUME; return InteractionResult.CONSUME;
} else { } else {

Datei anzeigen

@ -58,8 +58,8 @@ public class PillagerEntity extends AbstractIllagerEntity {
*/ */
protected void checkForCrossbow() { protected void checkForCrossbow() {
ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow(); ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow();
boolean hasCrossbow = this.hand.getId() == crossbow.getBedrockDefinition() boolean hasCrossbow = this.hand.getDefinition() == crossbow.getBedrockDefinition()
|| this.offHand.getId() == crossbow.getBedrockDefinition(); || this.offHand.getDefinition() == crossbow.getBedrockDefinition();
setFlag(EntityFlag.USING_ITEM, hasCrossbow); setFlag(EntityFlag.USING_ITEM, hasCrossbow);
setFlag(EntityFlag.CHARGED, hasCrossbow); setFlag(EntityFlag.CHARGED, hasCrossbow);

Datei anzeigen

@ -57,6 +57,6 @@ public class SpellcasterIllagerEntity extends AbstractIllagerEntity {
case 3 -> WOLOLO_PARTICLE_COLOR; case 3 -> WOLOLO_PARTICLE_COLOR;
default -> 0; default -> 0;
}; };
dirtyMetadata.put(EntityDataTypes.EVOKER_SPELL_COLOR, rgbData); dirtyMetadata.put(EntityDataTypes.EVOKER_SPELL_CASTING_COLOR, rgbData);
} }
} }

Datei anzeigen

@ -33,17 +33,25 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEnt
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition;
import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import lombok.Getter;
import lombok.Setter;
import net.kyori.adventure.text.Component;
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.*; import org.cloudburstmc.protocol.bedrock.data.Ability;
import org.cloudburstmc.protocol.bedrock.data.AbilityLayer;
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
import org.cloudburstmc.protocol.bedrock.data.GameType;
import org.cloudburstmc.protocol.bedrock.data.PlayerPermission;
import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission; import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
import org.cloudburstmc.protocol.bedrock.packet.*; import org.cloudburstmc.protocol.bedrock.packet.AddPlayerPacket;
import lombok.Getter; import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
import lombok.Setter; import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
import net.kyori.adventure.text.Component; import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
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;
import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.entity.type.LivingEntity;
@ -131,7 +139,7 @@ public class PlayerEntity extends LivingEntity {
addPlayerPacket.setRotation(getBedrockRotation()); addPlayerPacket.setRotation(getBedrockRotation());
addPlayerPacket.setMotion(motion); addPlayerPacket.setMotion(motion);
addPlayerPacket.setHand(hand); addPlayerPacket.setHand(hand);
addPlayerPacket.getAdventureSettings().setCommandPermission(CommandPermission.NORMAL); addPlayerPacket.getAdventureSettings().setCommandPermission(CommandPermission.ANY);
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER); addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
addPlayerPacket.setDeviceId(""); addPlayerPacket.setDeviceId("");
addPlayerPacket.setPlatformChatId(""); addPlayerPacket.setPlatformChatId("");
@ -283,8 +291,8 @@ public class PlayerEntity extends LivingEntity {
parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, tag.get("Variant").getValue()); parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, tag.get("Variant").getValue());
// Different position whether the parrot is left or right // Different position whether the parrot is left or right
float offset = isLeft ? 0.4f : -0.4f; float offset = isLeft ? 0.4f : -0.4f;
parrot.getDirtyMetadata().put(EntityDataTypes.RIDER_SEAT_POSITION, Vector3f.from(offset, -0.22, -0.1)); parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_OFFSET, Vector3f.from(offset, -0.22, -0.1));
parrot.getDirtyMetadata().put(EntityDataTypes.RIDER_ROTATION_LOCKED, 1); parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION, true);
parrot.updateBedrockMetadata(); parrot.updateBedrockMetadata();
SetEntityLinkPacket linkPacket = new SetEntityLinkPacket(); SetEntityLinkPacket linkPacket = new SetEntityLinkPacket();
EntityLinkData.Type type = isLeft ? EntityLinkData.Type.RIDER : EntityLinkData.Type.PASSENGER; EntityLinkData.Type type = isLeft ? EntityLinkData.Type.RIDER : EntityLinkData.Type.PASSENGER;
@ -342,11 +350,11 @@ public class PlayerEntity extends LivingEntity {
} }
needsUpdate = useGivenTeam && !newDisplayName.equals(nametag); needsUpdate = useGivenTeam && !newDisplayName.equals(nametag);
nametag = newDisplayName; nametag = newDisplayName;
dirtyMetadata.put(EntityDataTypes.NAMETAG, newDisplayName); dirtyMetadata.put(EntityDataTypes.NAME, newDisplayName);
} else if (useGivenTeam) { } else if (useGivenTeam) {
// The name has reset, if it was previously something else // The name has reset, if it was previously something else
needsUpdate = !newDisplayName.equals(nametag); needsUpdate = !newDisplayName.equals(nametag);
dirtyMetadata.put(EntityDataTypes.NAMETAG, this.username); dirtyMetadata.put(EntityDataTypes.NAME, this.username);
} else { } else {
needsUpdate = false; needsUpdate = false;
} }
@ -354,7 +362,7 @@ public class PlayerEntity extends LivingEntity {
if (needsUpdate) { if (needsUpdate) {
// Update the metadata as it won't be updated later // Update the metadata as it won't be updated later
SetEntityDataPacket packet = new SetEntityDataPacket(); SetEntityDataPacket packet = new SetEntityDataPacket();
packet.getMetadata().put(EntityDataTypes.NAMETAG, newDisplayName); packet.getMetadata().put(EntityDataTypes.NAME, newDisplayName);
packet.setRuntimeEntityId(geyserId); packet.setRuntimeEntityId(geyserId);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
} }
@ -407,13 +415,13 @@ public class PlayerEntity extends LivingEntity {
// providing the information // providing the information
SetEntityDataPacket packet = new SetEntityDataPacket(); SetEntityDataPacket packet = new SetEntityDataPacket();
packet.setRuntimeEntityId(geyserId); packet.setRuntimeEntityId(geyserId);
packet.getMetadata().put(EntityDataTypes.SCORE_TAG, displayString); packet.getMetadata().put(EntityDataTypes.SCORE, displayString);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
} }
} else if (valid) { } else if (valid) {
SetEntityDataPacket packet = new SetEntityDataPacket(); SetEntityDataPacket packet = new SetEntityDataPacket();
packet.setRuntimeEntityId(geyserId); packet.setRuntimeEntityId(geyserId);
packet.getMetadata().put(EntityDataTypes.SCORE_TAG, ""); packet.getMetadata().put(EntityDataTypes.SCORE, "");
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
} }
} }

Datei anzeigen

@ -167,7 +167,7 @@ public class SessionPlayerEntity extends PlayerEntity {
public void addFakeTradeExperience(int tradeXp) { public void addFakeTradeExperience(int tradeXp) {
fakeTradeXp += tradeXp; fakeTradeXp += tradeXp;
dirtyMetadata.put(EntityDataTypes.TRADE_XP, fakeTradeXp); dirtyMetadata.put(EntityDataTypes.TRADE_EXPERIENCE, fakeTradeXp);
} }
@Override @Override

Datei anzeigen

@ -56,8 +56,8 @@ public class SkullPlayerEntity extends PlayerEntity {
// Deliberately do not call super // Deliberately do not call super
// Set bounding box to almost nothing so the skull is able to be broken and not cause entity to cast a shadow // Set bounding box to almost nothing so the skull is able to be broken and not cause entity to cast a shadow
dirtyMetadata.put(EntityDataTypes.SCALE, 1.08f); dirtyMetadata.put(EntityDataTypes.SCALE, 1.08f);
dirtyMetadata.put(EntityDataTypes.BOUNDING_BOX_HEIGHT, 0.001f); dirtyMetadata.put(EntityDataTypes.HEIGHT, 0.001f);
dirtyMetadata.put(EntityDataTypes.BOUNDING_BOX_WIDTH, 0.001f); dirtyMetadata.put(EntityDataTypes.WIDTH, 0.001f);
setFlag(EntityFlag.CAN_SHOW_NAME, false); setFlag(EntityFlag.CAN_SHOW_NAME, false);
setFlag(EntityFlag.INVISIBLE, true); // Until the skin is loaded setFlag(EntityFlag.INVISIBLE, true); // Until the skin is loaded
} }
@ -76,7 +76,7 @@ public class SkullPlayerEntity extends PlayerEntity {
addPlayerPacket.setRotation(getBedrockRotation()); addPlayerPacket.setRotation(getBedrockRotation());
addPlayerPacket.setMotion(motion); addPlayerPacket.setMotion(motion);
addPlayerPacket.setHand(hand); addPlayerPacket.setHand(hand);
addPlayerPacket.getAdventureSettings().setCommandPermission(CommandPermission.NORMAL); addPlayerPacket.getAdventureSettings().setCommandPermission(CommandPermission.ANY);
addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER); addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER);
addPlayerPacket.setDeviceId(""); addPlayerPacket.setDeviceId("");
addPlayerPacket.setPlatformChatId(""); addPlayerPacket.setPlatformChatId("");

Datei anzeigen

@ -94,7 +94,6 @@ public class GeyserItemStack {
public ItemData getItemData(GeyserSession session) { public ItemData getItemData(GeyserSession session) {
ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack()); ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack());
itemData.setNetId(getNetId()); itemData.setNetId(getNetId());
itemData.setUsingNetId(true); // Seems silly - this should probably be on the protocol level
return itemData; return itemData;
} }

Datei anzeigen

@ -147,7 +147,7 @@ public class BlockInventoryHolder extends InventoryHolder {
// But send a container close packet because we aren't destroying the original. // But send a container close packet because we aren't destroying the original.
ContainerClosePacket packet = new ContainerClosePacket(); ContainerClosePacket packet = new ContainerClosePacket();
packet.setId((byte) inventory.getBedrockId()); packet.setId((byte) inventory.getBedrockId());
packet.setUnknownBool0(true); //TODO needs to be changed in Protocol to "server-side" or something packet.setServerInitiated(true);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
return; return;
} }

Datei anzeigen

@ -27,7 +27,6 @@ package org.geysermc.geyser.inventory.item;
import lombok.Getter; import lombok.Getter;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -39,70 +38,70 @@ import java.util.Map;
@Getter @Getter
@Accessors(fluent = true) @Accessors(fluent = true)
public class StoredItemMappings { public class StoredItemMappings {
private final ItemDefinition amethystShard; private final ItemMapping amethystShard;
private final ItemMapping bamboo; private final ItemMapping bamboo;
private final ItemMapping banner; private final ItemMapping banner;
private final ItemMapping barrier; private final ItemMapping barrier;
private final ItemDefinition bowl; private final ItemMapping bowl;
private final ItemDefinition bucket; private final ItemMapping bucket;
private final ItemDefinition chest; private final ItemMapping chest;
private final ItemMapping compass; private final ItemMapping compass;
private final ItemMapping crossbow; private final ItemMapping crossbow;
private final ItemMapping enchantedBook; private final ItemMapping enchantedBook;
private final ItemMapping fishingRod; private final ItemMapping fishingRod;
private final ItemDefinition flintAndSteel; private final ItemMapping flintAndSteel;
private final ItemDefinition frogspawn; private final ItemMapping frogspawn;
private final ItemDefinition goatHorn; private final ItemMapping goatHorn;
private final ItemDefinition glassBottle; private final ItemMapping glassBottle;
private final ItemDefinition goldenApple; private final ItemMapping goldenApple;
private final ItemDefinition goldIngot; private final ItemMapping goldIngot;
private final ItemDefinition ironIngot; private final ItemMapping ironIngot;
private final ItemDefinition lead; private final ItemMapping lead;
private final ItemDefinition lilyPad; private final ItemMapping lilyPad;
private final ItemMapping milkBucket; private final ItemMapping milkBucket;
private final ItemDefinition nameTag; private final ItemMapping nameTag;
private final ItemMapping powderSnowBucket; private final ItemMapping powderSnowBucket;
private final ItemMapping playerHead; private final ItemMapping playerHead;
private final ItemMapping egg; private final ItemMapping egg;
private final ItemDefinition saddle; private final ItemMapping saddle;
private final ItemDefinition shears; private final ItemMapping shears;
private final ItemMapping shield; private final ItemMapping shield;
private final ItemDefinition slimeBall; private final ItemMapping slimeBall;
private final ItemDefinition waterBucket; private final ItemMapping waterBucket;
private final ItemMapping wheat; private final ItemMapping wheat;
private final ItemMapping writableBook; private final ItemMapping writableBook;
public StoredItemMappings(Map<String, ItemMapping> itemMappings) { public StoredItemMappings(Map<String, ItemMapping> itemMappings) {
this.amethystShard = load(itemMappings, "amethyst_shard").getBedrockDefinition(); this.amethystShard = load(itemMappings, "amethyst_shard");
this.bamboo = load(itemMappings, "bamboo"); this.bamboo = load(itemMappings, "bamboo");
this.banner = load(itemMappings, "white_banner"); // As of 1.17.10, all banners have the same Bedrock ID this.banner = load(itemMappings, "white_banner"); // As of 1.17.10, all banners have the same Bedrock ID
this.barrier = load(itemMappings, "barrier"); this.barrier = load(itemMappings, "barrier");
this.bowl = load(itemMappings, "bowl").getBedrockDefinition(); this.bowl = load(itemMappings, "bowl");
this.bucket = load(itemMappings, "bucket").getBedrockDefinition(); this.bucket = load(itemMappings, "bucket");
this.chest = load(itemMappings, "chest").getBedrockDefinition(); this.chest = load(itemMappings, "chest");
this.compass = load(itemMappings, "compass"); this.compass = load(itemMappings, "compass");
this.crossbow = load(itemMappings, "crossbow"); this.crossbow = load(itemMappings, "crossbow");
this.enchantedBook = load(itemMappings, "enchanted_book"); this.enchantedBook = load(itemMappings, "enchanted_book");
this.fishingRod = load(itemMappings, "fishing_rod"); this.fishingRod = load(itemMappings, "fishing_rod");
this.flintAndSteel = load(itemMappings, "flint_and_steel").getBedrockDefinition(); this.flintAndSteel = load(itemMappings, "flint_and_steel");
this.frogspawn = load(itemMappings, "frogspawn").getBedrockDefinition(); this.frogspawn = load(itemMappings, "frogspawn");
this.goatHorn = load(itemMappings, "goat_horn").getBedrockDefinition(); this.goatHorn = load(itemMappings, "goat_horn");
this.glassBottle = load(itemMappings, "glass_bottle").getBedrockDefinition(); this.glassBottle = load(itemMappings, "glass_bottle");
this.goldenApple = load(itemMappings, "golden_apple").getBedrockDefinition(); this.goldenApple = load(itemMappings, "golden_apple");
this.goldIngot = load(itemMappings, "gold_ingot").getBedrockDefinition(); this.goldIngot = load(itemMappings, "gold_ingot");
this.ironIngot = load(itemMappings, "iron_ingot").getBedrockDefinition(); this.ironIngot = load(itemMappings, "iron_ingot");
this.lead = load(itemMappings, "lead").getBedrockDefinition(); this.lead = load(itemMappings, "lead");
this.lilyPad = load(itemMappings, "lily_pad").getBedrockDefinition(); this.lilyPad = load(itemMappings, "lily_pad");
this.milkBucket = load(itemMappings, "milk_bucket"); this.milkBucket = load(itemMappings, "milk_bucket");
this.nameTag = load(itemMappings, "name_tag").getBedrockDefinition(); this.nameTag = load(itemMappings, "name_tag");
this.powderSnowBucket = load(itemMappings, "powder_snow_bucket"); this.powderSnowBucket = load(itemMappings, "powder_snow_bucket");
this.playerHead = load(itemMappings, "player_head"); this.playerHead = load(itemMappings, "player_head");
this.egg = load(itemMappings, "egg"); this.egg = load(itemMappings, "egg");
this.saddle = load(itemMappings, "saddle").getBedrockDefinition(); this.saddle = load(itemMappings, "saddle");
this.shears = load(itemMappings, "shears").getBedrockDefinition(); this.shears = load(itemMappings, "shears");
this.shield = load(itemMappings, "shield"); this.shield = load(itemMappings, "shield");
this.slimeBall = load(itemMappings, "slime_ball").getBedrockDefinition(); this.slimeBall = load(itemMappings, "slime_ball");
this.waterBucket = load(itemMappings, "water_bucket").getBedrockDefinition(); this.waterBucket = load(itemMappings, "water_bucket");
this.wheat = load(itemMappings, "wheat"); this.wheat = load(itemMappings, "wheat");
this.writableBook = load(itemMappings, "writable_book"); this.writableBook = load(itemMappings, "writable_book");
} }

Datei anzeigen

@ -25,29 +25,17 @@
package org.geysermc.geyser.network; package org.geysermc.geyser.network;
import io.netty.channel.Channel;
import org.cloudburstmc.protocol.bedrock.BedrockPong;
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
import org.cloudburstmc.protocol.bedrock.BedrockSession;
import org.cloudburstmc.protocol.bedrock.codec.v554.Bedrock_v554;
import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultEventLoopGroup; import io.netty.channel.DefaultEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.concurrent.DefaultThreadFactory; import io.netty.util.concurrent.DefaultThreadFactory;
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
import org.cloudburstmc.protocol.bedrock.codec.v554.Bedrock_v554;
import org.cloudburstmc.protocol.bedrock.data.PacketCompressionAlgorithm;
import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.ping.GeyserPingInfo;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.translator.text.MessageTranslator;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List;
public class GeyserServerInitializer extends BedrockServerInitializer { public class GeyserServerInitializer extends BedrockServerInitializer {
private static final boolean PRINT_DEBUG_PINGS = Boolean.parseBoolean(System.getProperty("Geyser.PrintPingsInDebugMode", "true")); private static final boolean PRINT_DEBUG_PINGS = Boolean.parseBoolean(System.getProperty("Geyser.PrintPingsInDebugMode", "true"));
@ -179,12 +167,13 @@ public class GeyserServerInitializer extends BedrockServerInitializer {
try { try {
bedrockServerSession.setCodec(Bedrock_v554.CODEC); // Has the RequestNetworkSettingsPacket bedrockServerSession.setCodec(Bedrock_v554.CODEC); // Has the RequestNetworkSettingsPacket
bedrockServerSession.setLogging(true); bedrockServerSession.setLogging(true);
bedrockServerSession.setCompressionLevel(geyser.getConfig().getBedrock().getCompressionLevel()); bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next())));
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(geyser, new GeyserSession(geyser, bedrockServerSession, eventLoopGroup.next()))); bedrockServerSession.setCompression(PacketCompressionAlgorithm.ZLIB);
bedrockServerSession.setCompressionLevel(this.geyser.getConfig().getBedrock().getCompressionLevel());
// Set the packet codec to default just in case we need to send disconnect packets. // Set the packet codec to default just in case we need to send disconnect packets.
} catch (Throwable e) { } catch (Throwable e) {
// Error must be caught or it will be swallowed // Error must be caught or it will be swallowed
geyser.getLogger().error("Error occurred while initializing player!", e); this.geyser.getLogger().error("Error occurred while initializing player!", e);
bedrockServerSession.disconnect(e.getMessage()); bedrockServerSession.disconnect(e.getMessage());
} }
} }

Datei anzeigen

@ -31,7 +31,10 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.channel.socket.nio.NioDatagramChannel;
import org.cloudburstmc.netty.channel.raknet.RakChannelFactory; import org.cloudburstmc.netty.channel.raknet.RakChannelFactory;
import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption;
import org.cloudburstmc.protocol.bedrock.BedrockPong;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.network.GeyserServerInitializer; import org.geysermc.geyser.network.GeyserServerInitializer;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -62,7 +65,23 @@ public final class GeyserServer {
private ServerBootstrap createBootstrap(EventLoopGroup group) { private ServerBootstrap createBootstrap(EventLoopGroup group) {
return new ServerBootstrap() return new ServerBootstrap()
.channelFactory(RakChannelFactory.server(NioDatagramChannel.class)) .channelFactory(RakChannelFactory.server(NioDatagramChannel.class))
.option(RakChannelOption.RAK_ADVERTISEMENT, bedrockPong().toByteBuf())
.group(group) .group(group)
.childHandler(new GeyserServerInitializer(this.geyser)); .childHandler(new GeyserServerInitializer(this.geyser));
} }
// TODO: Temp
private BedrockPong bedrockPong() {
return new BedrockPong()
.edition("MCPE")
.gameType("Survival") // Can only be Survival or Creative as of 1.16.210.59
.nintendoLimited(false)
.protocolVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion())
.version(GameProtocol.DEFAULT_BEDROCK_CODEC.getMinecraftVersion()) // Required to not be empty as of 1.16.210.59. Can only contain . and numbers.
.ipv4Port(this.geyser.getConfig().getBedrock().port())
.motd(this.geyser.getConfig().getBedrock().primaryMotd())
.subMotd(this.geyser.getConfig().getBedrock().secondaryMotd())
.playerCount(geyser.getSessionManager().getSessions().size())
.maximumPlayerCount(this.geyser.getConfig().getMaxPlayers());
}
} }

Datei anzeigen

@ -29,8 +29,8 @@ import org.geysermc.geyser.registry.loader.RegistryLoader;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Map; import java.util.Map;
import java.util.OptionalInt; import java.util.Optional;
import java.util.function.ToIntFunction; import java.util.function.Function;
/** /**
* An abstract registry holding a map of various registrations as defined by {@link M}. * An abstract registry holding a map of various registrations as defined by {@link M}.
@ -58,18 +58,19 @@ public abstract class AbstractMappedRegistry<K, V, M extends Map<K, V>> extends
} }
/** /**
* Returns and maps the value by the given key if present. * Returns & maps the value by the given key if present.
* *
* @param key the key * @param key the key
* @param mapper the mapper * @param mapper the mapper
* @param <U> the type
* @return the mapped value from the given key if present * @return the mapped value from the given key if present
*/ */
public OptionalInt map(K key, ToIntFunction<? super V> mapper) { public <U> Optional<U> map(K key, Function<? super V, ? extends U> mapper) {
V value = this.get(key); V value = this.get(key);
if (value == null) { if (value == null) {
return OptionalInt.empty(); return Optional.empty();
} else { } else {
return OptionalInt.of(mapper.applyAsInt(value)); return Optional.ofNullable(mapper.apply(value));
} }
} }

Datei anzeigen

@ -29,6 +29,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.geysermc.geyser.util.FileUtils; import org.geysermc.geyser.util.FileUtils;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
@ -66,8 +67,8 @@ public class AnnotatedRegistryLoader<R, A extends Annotation, V> implements Regi
Map<R, V> entries = new Object2ObjectOpenHashMap<>(); Map<R, V> entries = new Object2ObjectOpenHashMap<>();
for (Class<?> clazz : FileUtils.getGeneratedClassesForAnnotation(input)) { for (Class<?> clazz : FileUtils.getGeneratedClassesForAnnotation(input)) {
try { try {
entries.put(this.mapper.apply(clazz.getAnnotation(this.annotation)), (V) clazz.newInstance()); entries.put(this.mapper.apply(clazz.getAnnotation(this.annotation)), (V) clazz.getConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException ex) { } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
} }

Datei anzeigen

@ -37,8 +37,7 @@ public class NbtRegistryLoader implements RegistryLoader<String, NbtMap> {
@Override @Override
public NbtMap load(String input) { public NbtMap load(String input) {
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(GeyserImpl.getInstance().getBootstrap().getResource(input), try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(GeyserImpl.getInstance().getBootstrap().getResource(input))) {
true, true)) {
return (NbtMap) nbtInputStream.readTag(); return (NbtMap) nbtInputStream.readTag();
} catch (Exception e) { } catch (Exception e) {
throw new AssertionError("Failed to load registrations for " + input, e); throw new AssertionError("Failed to load registrations for " + input, e);

Datei anzeigen

@ -27,8 +27,9 @@ package org.geysermc.geyser.registry.loader;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.protocol.data.game.level.particle.ParticleType; import com.github.steveice10.mc.protocol.data.game.level.particle.ParticleType;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.registry.type.ParticleMapping; import org.geysermc.geyser.registry.type.ParticleMapping;
@ -57,8 +58,20 @@ public class ParticleTypesRegistryLoader extends EffectRegistryLoader<Map<Partic
GeyserImpl.getInstance().getLogger().debug("Skipping particle mapping " + key + " because no Bedrock equivalent exists."); GeyserImpl.getInstance().getLogger().debug("Skipping particle mapping " + key + " because no Bedrock equivalent exists.");
continue; continue;
} }
LevelEventType type = null;
if (eventType != null) {
try {
// Check if we have a particle type mapping
type = org.cloudburstmc.protocol.bedrock.data.ParticleType.valueOf(eventType.asText().toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException ex) {
// No particle type; try level event
type = LevelEvent.valueOf(eventType.asText().toUpperCase(Locale.ROOT));
}
}
particles.put(ParticleType.valueOf(key), new ParticleMapping( particles.put(ParticleType.valueOf(key), new ParticleMapping(
eventType == null ? null : LevelEventType.valueOf(eventType.asText().toUpperCase(Locale.ROOT)), type,
bedrockId == null ? null : bedrockId.asText()) bedrockId == null ? null : bedrockId.asText())
); );
} }

Datei anzeigen

@ -83,9 +83,9 @@ public class PotionMixRegistryLoader implements RegistryLoader<Object, Set<Potio
for (ItemMapping entryInput : inputs) { for (ItemMapping entryInput : inputs) {
for (Potion potion : Potion.values()) { for (Potion potion : Potion.values()) {
potionMixes.add(new PotionMixData( potionMixes.add(new PotionMixData(
entryInput.getBedrockDefinition(), potion.getBedrockId(), entryInput.getBedrockDefinition().getRuntimeId(), potion.getBedrockId(),
fillerIngredient.getBedrockDefinition(), fillerIngredient.getBedrockData(), fillerIngredient.getBedrockDefinition().getRuntimeId(), fillerIngredient.getBedrockData(),
glassBottle.getBedrockDefinition(), glassBottle.getBedrockData()) glassBottle.getBedrockDefinition().getRuntimeId(), glassBottle.getBedrockData())
); );
} }
} }
@ -94,9 +94,9 @@ public class PotionMixRegistryLoader implements RegistryLoader<Object, Set<Potio
// Also adds glass bottle as input // Also adds glass bottle as input
for (ItemMapping ingredient : ingredients) { for (ItemMapping ingredient : ingredients) {
potionMixes.add(new PotionMixData( potionMixes.add(new PotionMixData(
glassBottle.getBedrockDefinition(), glassBottle.getBedrockData(), glassBottle.getBedrockDefinition().getRuntimeId(), glassBottle.getBedrockData(),
ingredient.getBedrockDefinition(), ingredient.getBedrockData(), ingredient.getBedrockDefinition().getRuntimeId(), ingredient.getBedrockData(),
glassBottle.getBedrockDefinition(), glassBottle.getBedrockData()) glassBottle.getBedrockDefinition().getRuntimeId(), glassBottle.getBedrockData())
); );
} }
return potionMixes; return potionMixes;

Datei anzeigen

@ -27,8 +27,8 @@ package org.geysermc.geyser.registry.loader;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent; import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.translator.level.event.LevelEventTranslator; import org.geysermc.geyser.translator.level.event.LevelEventTranslator;
import org.geysermc.geyser.translator.level.event.PlaySoundEventTranslator; import org.geysermc.geyser.translator.level.event.PlaySoundEventTranslator;
@ -59,7 +59,7 @@ public class SoundEventsRegistryLoader extends EffectRegistryLoader<Map<LevelEve
switch (type) { switch (type) {
case "soundLevel" -> { case "soundLevel" -> {
javaEffect = LevelEvent.valueOf(entry.getKey()); javaEffect = LevelEvent.valueOf(entry.getKey());
LevelEventType levelEventType = LevelEventType.valueOf(node.get("name").asText()); LevelEventType levelEventType = org.cloudburstmc.protocol.bedrock.data.LevelEvent.valueOf(node.get("name").asText());
int data = node.has("data") ? node.get("data").intValue() : 0; int data = node.has("data") ? node.get("data").intValue() : 0;
transformer = new SoundLevelEventTranslator(levelEventType, data); transformer = new SoundLevelEventTranslator(levelEventType, data);
} }

Datei anzeigen

@ -44,6 +44,8 @@ import org.cloudburstmc.protocol.bedrock.codec.v527.Bedrock_v527;
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544; import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleBlockDefinition; import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleBlockDefinition;
import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleDefinitionRegistry;
import org.cloudburstmc.protocol.common.DefinitionRegistry;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.level.physics.PistonBehavior; import org.geysermc.geyser.level.physics.PistonBehavior;
@ -55,6 +57,7 @@ import org.geysermc.geyser.util.BlockUtils;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque; import java.util.Deque;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -126,6 +129,7 @@ public final class BlockRegistryPopulator {
BiFunction<String, NbtMapBuilder, String> stateMapper = blockMappers.getOrDefault(palette.getKey(), emptyMapper); BiFunction<String, NbtMapBuilder, String> stateMapper = blockMappers.getOrDefault(palette.getKey(), emptyMapper);
BlockDefinition[] javaToBedrockBlocks = new BlockDefinition[BLOCKS_JSON.size()]; BlockDefinition[] javaToBedrockBlocks = new BlockDefinition[BLOCKS_JSON.size()];
DefinitionRegistry.Builder<BlockDefinition> registry = SimpleDefinitionRegistry.builder();
Map<String, NbtMap> flowerPotBlocks = new Object2ObjectOpenHashMap<>(); Map<String, NbtMap> flowerPotBlocks = new Object2ObjectOpenHashMap<>();
Map<NbtMap, BlockDefinition> itemFrames = new Object2ObjectOpenHashMap<>(); Map<NbtMap, BlockDefinition> itemFrames = new Object2ObjectOpenHashMap<>();
@ -173,6 +177,8 @@ public final class BlockRegistryPopulator {
javaToBedrockBlocks[javaRuntimeId] = bedrockDefinition; javaToBedrockBlocks[javaRuntimeId] = bedrockDefinition;
} }
Arrays.stream(javaToBedrockBlocks).distinct().forEach(registry::add);
if (commandBlockDefinition == null) { if (commandBlockDefinition == null) {
throw new AssertionError("Unable to find command block in palette"); throw new AssertionError("Unable to find command block in palette");
} }
@ -205,6 +211,7 @@ public final class BlockRegistryPopulator {
builder.bedrockBlockPalette(blocksTag); builder.bedrockBlockPalette(blocksTag);
BlockRegistries.BLOCKS.register(palette.getKey().valueInt(), builder.blockStateVersion(stateVersion) BlockRegistries.BLOCKS.register(palette.getKey().valueInt(), builder.blockStateVersion(stateVersion)
.definitionRegistry(registry.build())
.javaToBedrockBlocks(javaToBedrockBlocks) .javaToBedrockBlocks(javaToBedrockBlocks)
.itemFrames(itemFrames) .itemFrames(itemFrames)
.flowerPotBlocks(flowerPotBlocks) .flowerPotBlocks(flowerPotBlocks)

Datei anzeigen

@ -33,6 +33,7 @@ import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.nbt.NbtMapBuilder;
import com.nukkitx.nbt.NbtType; import com.nukkitx.nbt.NbtType;
import com.nukkitx.nbt.NbtUtils; import com.nukkitx.nbt.NbtUtils;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
@ -40,9 +41,9 @@ import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectIntPair;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.protocol.bedrock.codec.v527.Bedrock_v527; import org.cloudburstmc.protocol.bedrock.codec.v527.Bedrock_v527;
@ -50,8 +51,10 @@ import org.cloudburstmc.protocol.bedrock.codec.v534.Bedrock_v534;
import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544; import org.cloudburstmc.protocol.bedrock.codec.v544.Bedrock_v544;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.defintions.SimpleDefinitionRegistry;
import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.common.DefinitionRegistry;
import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.item.custom.CustomItemData; import org.geysermc.geyser.api.item.custom.CustomItemData;
@ -79,7 +82,6 @@ import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -176,7 +178,6 @@ public class ItemRegistryPopulator {
TypeReference<List<PaletteItem>> paletteEntriesType = new TypeReference<>() {}; TypeReference<List<PaletteItem>> paletteEntriesType = new TypeReference<>() {};
// Used to get the Bedrock namespaced ID (in instances where there are small differences) // Used to get the Bedrock namespaced ID (in instances where there are small differences)
Map<String, ItemDefinition> bedrockIdentifierToDefinition = new HashMap<>();
List<String> itemNames = new ArrayList<>(); List<String> itemNames = new ArrayList<>();
@ -191,7 +192,8 @@ public class ItemRegistryPopulator {
int nextFreeBedrockId = 0; int nextFreeBedrockId = 0;
List<ComponentItemData> componentItemData = new ObjectArrayList<>(); List<ComponentItemData> componentItemData = new ObjectArrayList<>();
Map<String, ItemDefinition> definitions = new Object2ObjectOpenHashMap<>(); DefinitionRegistry.Builder<ItemDefinition> registry = SimpleDefinitionRegistry.builder();
Map<String, ItemDefinition> definitions = new Object2ObjectLinkedOpenHashMap<>();
for (PaletteItem entry : itemEntries) { for (PaletteItem entry : itemEntries) {
int id = entry.getId(); int id = entry.getId();
@ -201,7 +203,7 @@ public class ItemRegistryPopulator {
ItemDefinition definition = new ItemDefinition(entry.getName(), id, false); ItemDefinition definition = new ItemDefinition(entry.getName(), id, false);
definitions.put(entry.getName(), definition); definitions.put(entry.getName(), definition);
bedrockIdentifierToDefinition.put(entry.getName(), definition); registry.add(definition);
} }
Object2IntMap<String> bedrockBlockIdOverrides = new Object2IntOpenHashMap<>(); Object2IntMap<String> bedrockBlockIdOverrides = new Object2IntOpenHashMap<>();
@ -266,6 +268,7 @@ public class ItemRegistryPopulator {
// Bedrock-only banner patterns // Bedrock-only banner patterns
continue; continue;
} }
ItemDefinition definition = definitions.get(identifier); ItemDefinition definition = definitions.get(identifier);
creativeItems.add(ItemData.builder() creativeItems.add(ItemData.builder()
.definition(definition) .definition(definition)
@ -328,7 +331,7 @@ public class ItemRegistryPopulator {
} }
String bedrockIdentifier = mappingItem.getBedrockIdentifier(); String bedrockIdentifier = mappingItem.getBedrockIdentifier();
ItemDefinition definition = bedrockIdentifierToDefinition.get(bedrockIdentifier); ItemDefinition definition = definitions.get(bedrockIdentifier);
if (definition == null) { if (definition == null) {
throw new RuntimeException("Missing Bedrock ItemDefinition in mappings: " + bedrockIdentifier); throw new RuntimeException("Missing Bedrock ItemDefinition in mappings: " + bedrockIdentifier);
} }
@ -483,7 +486,7 @@ public class ItemRegistryPopulator {
} }
// Add the custom item properties, if applicable // Add the custom item properties, if applicable
List<ObjectIntPair<CustomItemOptions>> customItemOptions; List<Pair<CustomItemOptions, ItemDefinition>> customItemOptions;
Collection<CustomItemData> customItemsToLoad = customItems.get(javaIdentifier); Collection<CustomItemData> customItemsToLoad = customItems.get(javaIdentifier);
if (customItemsAllowed && !customItemsToLoad.isEmpty()) { if (customItemsAllowed && !customItemsToLoad.isEmpty()) {
customItemOptions = new ObjectArrayList<>(customItemsToLoad.size()); customItemOptions = new ObjectArrayList<>(customItemsToLoad.size());
@ -504,9 +507,10 @@ public class ItemRegistryPopulator {
); );
// StartGamePacket entry - needed for Bedrock to recognize the item through the protocol // StartGamePacket entry - needed for Bedrock to recognize the item through the protocol
definitions.put(customMapping.stringId(), customMapping.itemDefinition()); definitions.put(customMapping.stringId(), customMapping.itemDefinition());
registry.add(customMapping.itemDefinition());
// ComponentItemData - used to register some custom properties // ComponentItemData - used to register some custom properties
componentItemData.add(customMapping.componentItemData()); componentItemData.add(customMapping.componentItemData());
customItemOptions.add(ObjectIntPair.of(customItem.customItemOptions(), customProtocolId)); customItemOptions.add(Pair.of(customItem.customItemOptions(), customMapping.itemDefinition()));
customIdMappings.put(customMapping.integerId(), customMapping.stringId()); customIdMappings.put(customMapping.integerId(), customMapping.stringId());
} }
@ -577,6 +581,7 @@ public class ItemRegistryPopulator {
ItemDefinition definition = new ItemDefinition("geysermc:furnace_minecart", (short) furnaceMinecartId, true); ItemDefinition definition = new ItemDefinition("geysermc:furnace_minecart", (short) furnaceMinecartId, true);
definitions.put("geysermc:furnace_minecart", definition); definitions.put("geysermc:furnace_minecart", definition);
registry.add(definition);
mappings.set(javaFurnaceMinecartId, ItemMapping.builder() mappings.set(javaFurnaceMinecartId, ItemMapping.builder()
.javaIdentifier("minecraft:furnace_minecart") .javaIdentifier("minecraft:furnace_minecart")
@ -661,6 +666,7 @@ public class ItemRegistryPopulator {
ItemMappings itemMappings = ItemMappings.builder() ItemMappings itemMappings = ItemMappings.builder()
.items(mappings.toArray(new ItemMapping[0])) .items(mappings.toArray(new ItemMapping[0]))
.creativeItems(creativeItems.toArray(new ItemData[0])) .creativeItems(creativeItems.toArray(new ItemData[0]))
.definitionRegistry(registry.build())
.itemDefinitions(List.copyOf(definitions.values())) .itemDefinitions(List.copyOf(definitions.values()))
.itemNames(itemNames.toArray(new String[0])) .itemNames(itemNames.toArray(new String[0]))
.storedItems(new StoredItemMappings(identifierToMapping)) .storedItems(new StoredItemMappings(identifierToMapping))

Datei anzeigen

@ -32,6 +32,8 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
import lombok.Builder; import lombok.Builder;
import lombok.Value; import lombok.Value;
import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition;
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
import org.cloudburstmc.protocol.common.DefinitionRegistry;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -46,6 +48,7 @@ public class BlockMappings {
int blockStateVersion; int blockStateVersion;
BlockDefinition[] javaToBedrockBlocks; BlockDefinition[] javaToBedrockBlocks;
DefinitionRegistry<BlockDefinition> definitionRegistry;
NbtList<NbtMap> bedrockBlockPalette; NbtList<NbtMap> bedrockBlockPalette;

Datei anzeigen

@ -32,6 +32,7 @@ import lombok.Value;
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.common.DefinitionRegistry;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.item.StoredItemMappings; import org.geysermc.geyser.inventory.item.StoredItemMappings;
@ -56,6 +57,7 @@ public class ItemMappings {
ItemData[] creativeItems; ItemData[] creativeItems;
List<ItemDefinition> itemDefinitions; List<ItemDefinition> itemDefinitions;
DefinitionRegistry<ItemDefinition> definitionRegistry;
StoredItemMappings storedItems; StoredItemMappings storedItems;
String[] itemNames; String[] itemNames;

Datei anzeigen

@ -26,18 +26,10 @@
package org.geysermc.geyser.registry.type; package org.geysermc.geyser.registry.type;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.geysermc.geyser.session.GeyserSession; import org.cloudburstmc.protocol.bedrock.data.ParticleType;
import javax.annotation.ParametersAreNullableByDefault; import javax.annotation.ParametersAreNullableByDefault;
@ParametersAreNullableByDefault @ParametersAreNullableByDefault
public record ParticleMapping(LevelEventType levelEventType, String identifier) { public record ParticleMapping(LevelEventType levelEventType, String identifier) {
public int getParticleId(GeyserSession session) {
if (this.levelEventType == null) {
return -1;
}
return session.getUpstream().getSession().getPacketCodec().getHelper().getLevelEventId(this.levelEventType) & ~0x4000;
}
} }

Datei anzeigen

@ -66,6 +66,7 @@ import com.github.steveice10.packetlib.event.session.SessionAdapter;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
import com.github.steveice10.packetlib.tcp.TcpClientSession; import com.github.steveice10.packetlib.tcp.TcpClientSession;
import com.github.steveice10.packetlib.tcp.TcpSession; import com.github.steveice10.packetlib.tcp.TcpSession;
import com.nimbusds.jwt.SignedJWT;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.EventLoop; import io.netty.channel.EventLoop;
@ -205,7 +206,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
* Used for Floodgate skin uploading * Used for Floodgate skin uploading
*/ */
@Setter @Setter
private JsonNode certChainData; private List<SignedJWT> certChainData;
@Accessors(fluent = true) @Accessors(fluent = true)
@Setter @Setter
@ -1438,6 +1439,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
} }
private void startGame() { private void startGame() {
this.upstream.getCodecHelper().setItemDefinitions(this.itemMappings.getDefinitionRegistry());
this.upstream.getCodecHelper().setBlockDefinitions(this.blockMappings.getDefinitionRegistry());
StartGamePacket startGamePacket = new StartGamePacket(); StartGamePacket startGamePacket = new StartGamePacket();
startGamePacket.setUniqueEntityId(playerEntity.getGeyserId()); startGamePacket.setUniqueEntityId(playerEntity.getGeyserId());
startGamePacket.setRuntimeEntityId(playerEntity.getGeyserId()); startGamePacket.setRuntimeEntityId(playerEntity.getGeyserId());
@ -1489,7 +1493,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
startGamePacket.setMultiplayerCorrelationId(""); startGamePacket.setMultiplayerCorrelationId("");
startGamePacket.setItemDefinitions(this.itemMappings.getItemDefinitions()); startGamePacket.setItemDefinitions(this.itemMappings.getItemDefinitions());
startGamePacket.setBlockPalette(this.blockMappings.getBedrockBlockPalette()); // startGamePacket.setBlockPalette(this.blockMappings.getBedrockBlockPalette());
startGamePacket.setVanillaVersion("*"); startGamePacket.setVanillaVersion("*");
startGamePacket.setInventoriesServerAuthoritative(true); startGamePacket.setInventoriesServerAuthoritative(true);

Datei anzeigen

@ -25,13 +25,15 @@
package org.geysermc.geyser.session.cache; package org.geysermc.geyser.session.cache;
import lombok.AllArgsConstructor;
import net.kyori.adventure.text.Component;
import org.cloudburstmc.math.vector.Vector2f;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataMap;
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.BossEventPacket; import org.cloudburstmc.protocol.bedrock.packet.BossEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket; import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket;
import lombok.AllArgsConstructor;
import net.kyori.adventure.text.Component;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
@ -116,12 +118,12 @@ public class BossBar {
addEntityPacket.setIdentifier("minecraft:creeper"); addEntityPacket.setIdentifier("minecraft:creeper");
addEntityPacket.setEntityType(33); addEntityPacket.setEntityType(33);
addEntityPacket.setPosition(session.getPlayerEntity().getPosition().sub(0D, -10D, 0D)); addEntityPacket.setPosition(session.getPlayerEntity().getPosition().sub(0D, -10D, 0D));
addEntityPacket.setRotation(Vector3f.ZERO); addEntityPacket.setRotation(Vector2f.ZERO);
addEntityPacket.setMotion(Vector3f.ZERO); addEntityPacket.setMotion(Vector3f.ZERO);
addEntityPacket.getMetadata() EntityDataMap metadata = addEntityPacket.getMetadata();
.putFloat(EntityDataTypes.SCALE, 0F) metadata.put(EntityDataTypes.SCALE, 0F);
.putFloat(EntityDataTypes.BOUNDING_BOX_WIDTH, 0F) metadata.put(EntityDataTypes.WIDTH, 0F);
.putFloat(EntityDataTypes.BOUNDING_BOX_HEIGHT, 0F); metadata.put(EntityDataTypes.HEIGHT, 0F);
session.sendUpstreamPacket(addEntityPacket); session.sendUpstreamPacket(addEntityPacket);
} }

Datei anzeigen

@ -28,6 +28,7 @@ package org.geysermc.geyser.session.cache;
import org.cloudburstmc.math.GenericMath; import org.cloudburstmc.math.GenericMath;
import org.cloudburstmc.math.vector.Vector2d; import org.cloudburstmc.math.vector.Vector2d;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import lombok.Getter; import lombok.Getter;
@ -242,7 +243,7 @@ public class WorldBorder {
} }
} }
private static final LevelEventType WORLD_BORDER_PARTICLE = LevelEventType.PARTICLE_DENY_BLOCK; private static final LevelEventType WORLD_BORDER_PARTICLE = LevelEvent.PARTICLE_DENY_BLOCK;
/** /**
* Draws a wall of particles where the world border resides * Draws a wall of particles where the world border resides

Datei anzeigen

@ -29,6 +29,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.nimbusds.jwt.SignedJWT;
import lombok.Getter; import lombok.Getter;
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels; import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
import org.geysermc.floodgate.util.WebsocketEventType; import org.geysermc.floodgate.util.WebsocketEventType;
@ -184,13 +185,13 @@ public final class FloodgateSkinUploader {
}; };
} }
public void uploadSkin(JsonNode chainData, String clientData) { public void uploadSkin(List<SignedJWT> chainData, String clientData) {
if (chainData == null || !chainData.isArray() || clientData == null) { if (chainData == null || clientData == null) {
return; return;
} }
ObjectNode node = JACKSON.createObjectNode(); ObjectNode node = JACKSON.createObjectNode();
node.set("chain_data", chainData); node.put("chain_data", chainData.toString()); // TODO: Check this
node.put("client_data", clientData); node.put("client_data", clientData);
// The reason why I don't like Jackson // The reason why I don't like Jackson

Datei anzeigen

@ -28,11 +28,11 @@ package org.geysermc.geyser.translator.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData; import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeOptionalStackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeOptionalStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
import org.geysermc.geyser.inventory.AnvilContainer; import org.geysermc.geyser.inventory.AnvilContainer;
import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
@ -54,7 +54,7 @@ public class AnvilInventoryTranslator extends AbstractBlockInventoryTranslator {
} }
@Override @Override
protected ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { protected ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
// Guarded by shouldHandleRequestFirst check // Guarded by shouldHandleRequestFirst check
CraftRecipeOptionalStackRequestActionData data = (CraftRecipeOptionalStackRequestActionData) request.getActions()[0]; CraftRecipeOptionalStackRequestActionData data = (CraftRecipeOptionalStackRequestActionData) request.getActions()[0];
AnvilContainer container = (AnvilContainer) inventory; AnvilContainer container = (AnvilContainer) inventory;

Datei anzeigen

@ -28,7 +28,11 @@ package org.geysermc.geyser.translator.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData; import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.Container;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory;
import org.geysermc.geyser.inventory.SlotType;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
public abstract class BaseInventoryTranslator extends InventoryTranslator { public abstract class BaseInventoryTranslator extends InventoryTranslator {

Datei anzeigen

@ -27,18 +27,18 @@ package org.geysermc.geyser.translator.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetBeaconPacket;
import org.cloudburstmc.math.vector.Vector3i;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.nbt.NbtMapBuilder;
import it.unimi.dsi.fastutil.ints.IntSets;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData; import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.BeaconPaymentStackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.BeaconPaymentStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
import it.unimi.dsi.fastutil.ints.IntSets;
import org.geysermc.geyser.inventory.BeaconContainer; import org.geysermc.geyser.inventory.BeaconContainer;
import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
@ -110,7 +110,7 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator
} }
@Override @Override
public ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
// Input a beacon payment // Input a beacon payment
BeaconPaymentStackRequestActionData beaconPayment = (BeaconPaymentStackRequestActionData) request.getActions()[0]; BeaconPaymentStackRequestActionData beaconPayment = (BeaconPaymentStackRequestActionData) request.getActions()[0];
ServerboundSetBeaconPacket packet = new ServerboundSetBeaconPacket(toJava(beaconPayment.getPrimaryEffect()), toJava(beaconPayment.getSecondaryEffect())); ServerboundSetBeaconPacket packet = new ServerboundSetBeaconPacket(toJava(beaconPayment.getPrimaryEffect()), toJava(beaconPayment.getSecondaryEffect()));

Datei anzeigen

@ -27,17 +27,21 @@ package org.geysermc.geyser.translator.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
import it.unimi.dsi.fastutil.ints.IntSets;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData; import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData; import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket;
import it.unimi.dsi.fastutil.ints.IntSets; import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.EnchantingContainer;
import org.geysermc.geyser.inventory.GeyserEnchantOption;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory;
import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.inventory.item.Enchantment;
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -108,7 +112,7 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla
} }
@Override @Override
public ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
// Client has requested an item to be enchanted // Client has requested an item to be enchanted
CraftRecipeStackRequestActionData craftRecipeData = (CraftRecipeStackRequestActionData) request.getActions()[0]; CraftRecipeStackRequestActionData craftRecipeData = (CraftRecipeStackRequestActionData) request.getActions()[0];
EnchantingContainer enchantingInventory = (EnchantingContainer) inventory; EnchantingContainer enchantingInventory = (EnchantingContainer) inventory;

Datei anzeigen

@ -30,8 +30,12 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient; import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.Tag; import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerEntry;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemEntry;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.ResponseStatus;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData; import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.*; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.*;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket; import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
@ -144,7 +148,7 @@ public abstract class InventoryTranslator {
/** /**
* If {@link #shouldHandleRequestFirst(StackRequestActionData, Inventory)} returns true, this will be called * If {@link #shouldHandleRequestFirst(StackRequestActionData, Inventory)} returns true, this will be called
*/ */
protected ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { protected ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
return rejectRequest(request); return rejectRequest(request);
} }
@ -152,7 +156,7 @@ public abstract class InventoryTranslator {
boolean refresh = false; boolean refresh = false;
ItemStackResponsePacket responsePacket = new ItemStackResponsePacket(); ItemStackResponsePacket responsePacket = new ItemStackResponsePacket();
for (ItemStackRequest request : requests) { for (ItemStackRequest request : requests) {
ItemStackResponsePacket.Response response; ItemStackResponse response;
if (request.getActions().length > 0) { if (request.getActions().length > 0) {
StackRequestActionData firstAction = request.getActions()[0]; StackRequestActionData firstAction = request.getActions()[0];
if (shouldHandleRequestFirst(firstAction, inventory)) { if (shouldHandleRequestFirst(firstAction, inventory)) {
@ -172,7 +176,7 @@ public abstract class InventoryTranslator {
response = rejectRequest(request); response = rejectRequest(request);
} }
if (response.getResult() != ItemStackResponsePacket.ResponseStatus.OK) { if (response.getResult() != ResponseStatus.OK) {
// Sync our copy of the inventory with Bedrock's to prevent desyncs // Sync our copy of the inventory with Bedrock's to prevent desyncs
refresh = true; refresh = true;
} }
@ -190,7 +194,7 @@ public abstract class InventoryTranslator {
inventory.resetNextStateId(); inventory.resetNextStateId();
} }
public ItemStackResponsePacket.Response translateRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
ClickPlan plan = new ClickPlan(session, this, inventory); ClickPlan plan = new ClickPlan(session, this, inventory);
IntSet affectedSlots = new IntOpenHashSet(); IntSet affectedSlots = new IntOpenHashSet();
for (StackRequestActionData action : request.getActions()) { for (StackRequestActionData action : request.getActions()) {
@ -423,7 +427,7 @@ public abstract class InventoryTranslator {
return acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots)); return acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots));
} }
public ItemStackResponsePacket.Response translateCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
int resultSize = 0; int resultSize = 0;
int timesCrafted; int timesCrafted;
CraftState craftState = CraftState.START; CraftState craftState = CraftState.START;
@ -528,7 +532,7 @@ public abstract class InventoryTranslator {
return acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots)); return acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots));
} }
public ItemStackResponsePacket.Response translateAutoCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateAutoCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
final int gridSize = getGridSize(); final int gridSize = getGridSize();
if (gridSize == -1) { if (gridSize == -1) {
return rejectRequest(request); return rejectRequest(request);
@ -715,7 +719,7 @@ public abstract class InventoryTranslator {
/** /**
* Handled in {@link PlayerInventoryTranslator} * Handled in {@link PlayerInventoryTranslator}
*/ */
protected ItemStackResponsePacket.Response translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { protected ItemStackResponse translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
return rejectRequest(request); return rejectRequest(request);
} }
@ -750,14 +754,14 @@ public abstract class InventoryTranslator {
} }
} }
protected static ItemStackResponsePacket.Response acceptRequest(ItemStackRequest request, List<ItemStackResponsePacket.ContainerEntry> containerEntries) { protected static ItemStackResponse acceptRequest(ItemStackRequest request, List<ContainerEntry> containerEntries) {
return new ItemStackResponsePacket.Response(ItemStackResponsePacket.ResponseStatus.OK, request.getRequestId(), containerEntries); return new ItemStackResponse(ResponseStatus.OK, request.getRequestId(), containerEntries);
} }
/** /**
* Reject an incorrect ItemStackRequest. * Reject an incorrect ItemStackRequest.
*/ */
protected static ItemStackResponsePacket.Response rejectRequest(ItemStackRequest request) { protected static ItemStackResponse rejectRequest(ItemStackRequest request) {
return rejectRequest(request, true); return rejectRequest(request, true);
} }
@ -767,11 +771,11 @@ public abstract class InventoryTranslator {
* @param throwError whether this request was truly erroneous (true), or known as an outcome and should not be treated * @param throwError whether this request was truly erroneous (true), or known as an outcome and should not be treated
* as bad (false). * as bad (false).
*/ */
protected static ItemStackResponsePacket.Response rejectRequest(ItemStackRequest request, boolean throwError) { protected static ItemStackResponse rejectRequest(ItemStackRequest request, boolean throwError) {
if (throwError && GeyserImpl.getInstance().getConfig().isDebugMode()) { if (throwError && GeyserImpl.getInstance().getConfig().isDebugMode()) {
new Throwable("DEBUGGING: ItemStackRequest rejected " + request.toString()).printStackTrace(); new Throwable("DEBUGGING: ItemStackRequest rejected " + request.toString()).printStackTrace();
} }
return new ItemStackResponsePacket.Response(ItemStackResponsePacket.ResponseStatus.ERROR, request.getRequestId(), Collections.emptyList()); return new ItemStackResponse(ResponseStatus.ERROR, request.getRequestId(), Collections.emptyList());
} }
/** /**
@ -842,30 +846,30 @@ public abstract class InventoryTranslator {
return -1; return -1;
} }
protected final List<ItemStackResponsePacket.ContainerEntry> makeContainerEntries(GeyserSession session, Inventory inventory, IntSet affectedSlots) { protected final List<ContainerEntry> makeContainerEntries(GeyserSession session, Inventory inventory, IntSet affectedSlots) {
Map<ContainerSlotType, List<ItemStackResponsePacket.ItemEntry>> containerMap = new HashMap<>(); Map<ContainerSlotType, List<ItemEntry>> containerMap = new HashMap<>();
// Manually call iterator to prevent Integer boxing // Manually call iterator to prevent Integer boxing
IntIterator it = affectedSlots.iterator(); IntIterator it = affectedSlots.iterator();
while (it.hasNext()) { while (it.hasNext()) {
int slot = it.nextInt(); int slot = it.nextInt();
BedrockContainerSlot bedrockSlot = javaSlotToBedrockContainer(slot); BedrockContainerSlot bedrockSlot = javaSlotToBedrockContainer(slot);
List<ItemStackResponsePacket.ItemEntry> list = containerMap.computeIfAbsent(bedrockSlot.container(), k -> new ArrayList<>()); List<ItemEntry> list = containerMap.computeIfAbsent(bedrockSlot.container(), k -> new ArrayList<>());
list.add(makeItemEntry(session, bedrockSlot.slot(), inventory.getItem(slot))); list.add(makeItemEntry(session, bedrockSlot.slot(), inventory.getItem(slot)));
} }
List<ItemStackResponsePacket.ContainerEntry> containerEntries = new ArrayList<>(); List<ContainerEntry> containerEntries = new ArrayList<>();
for (Map.Entry<ContainerSlotType, List<ItemStackResponsePacket.ItemEntry>> entry : containerMap.entrySet()) { for (Map.Entry<ContainerSlotType, List<ItemEntry>> entry : containerMap.entrySet()) {
containerEntries.add(new ItemStackResponsePacket.ContainerEntry(entry.getKey(), entry.getValue())); containerEntries.add(new ContainerEntry(entry.getKey(), entry.getValue()));
} }
ItemStackResponsePacket.ItemEntry cursorEntry = makeItemEntry(session, 0, session.getPlayerInventory().getCursor()); ItemEntry cursorEntry = makeItemEntry(session, 0, session.getPlayerInventory().getCursor());
containerEntries.add(new ItemStackResponsePacket.ContainerEntry(ContainerSlotType.CURSOR, Collections.singletonList(cursorEntry))); containerEntries.add(new ContainerEntry(ContainerSlotType.CURSOR, Collections.singletonList(cursorEntry)));
return containerEntries; return containerEntries;
} }
private static ItemStackResponsePacket.ItemEntry makeItemEntry(GeyserSession session, int bedrockSlot, GeyserItemStack itemStack) { private static ItemEntry makeItemEntry(GeyserSession session, int bedrockSlot, GeyserItemStack itemStack) {
ItemStackResponsePacket.ItemEntry itemEntry; ItemEntry itemEntry;
if (!itemStack.isEmpty()) { if (!itemStack.isEmpty()) {
// As of 1.16.210: Bedrock needs confirmation on what the current item durability is. // As of 1.16.210: Bedrock needs confirmation on what the current item durability is.
// If 0 is sent, then Bedrock thinks the item is not damaged // If 0 is sent, then Bedrock thinks the item is not damaged
@ -877,9 +881,9 @@ public abstract class InventoryTranslator {
} }
} }
itemEntry = new ItemStackResponsePacket.ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) itemStack.getAmount(), itemStack.getNetId(), "", durability); itemEntry = new ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) itemStack.getAmount(), itemStack.getNetId(), "", durability);
} else { } else {
itemEntry = new ItemStackResponsePacket.ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) 0, 0, "", 0); itemEntry = new ItemEntry((byte) bedrockSlot, (byte) bedrockSlot, (byte) 0, 0, "", 0);
} }
return itemEntry; return itemEntry;
} }

Datei anzeigen

@ -30,17 +30,17 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtType; import com.nukkitx.nbt.NbtType;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData; import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftLoomStackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftLoomStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftResultsDeprecatedStackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftResultsDeprecatedStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.geysermc.geyser.inventory.BedrockContainerSlot; import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
@ -123,7 +123,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
} }
@Override @Override
public ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
StackRequestActionData headerData = request.getActions()[0]; StackRequestActionData headerData = request.getActions()[0];
StackRequestActionData data = request.getActions()[1]; StackRequestActionData data = request.getActions()[1];
if (!(headerData instanceof CraftLoomStackRequestActionData)) { if (!(headerData instanceof CraftLoomStackRequestActionData)) {

Datei anzeigen

@ -32,14 +32,18 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData; import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.AutoCraftRecipeStackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.AutoCraftRecipeStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
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;
import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.MerchantContainer;
import org.geysermc.geyser.inventory.PlayerInventory;
import org.geysermc.geyser.inventory.SlotType;
import org.geysermc.geyser.inventory.updater.InventoryUpdater; import org.geysermc.geyser.inventory.updater.InventoryUpdater;
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -104,8 +108,8 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
@Override @Override
protected void initializeMetadata() { protected void initializeMetadata() {
dirtyMetadata.put(EntityDataTypes.SCALE, 0f); dirtyMetadata.put(EntityDataTypes.SCALE, 0f);
dirtyMetadata.put(EntityDataTypes.BOUNDING_BOX_WIDTH, 0f); dirtyMetadata.put(EntityDataTypes.WIDTH, 0f);
dirtyMetadata.put(EntityDataTypes.BOUNDING_BOX_HEIGHT, 0f); dirtyMetadata.put(EntityDataTypes.HEIGHT, 0f);
} }
}; };
villager.spawnEntity(); villager.spawnEntity();
@ -134,7 +138,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
} }
@Override @Override
public ItemStackResponsePacket.Response translateCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
// Behavior as of 1.18.10. // Behavior as of 1.18.10.
// We set the net ID to the trade index + 1. This doesn't appear to cause issues and means we don't have to // We set the net ID to the trade index + 1. This doesn't appear to cause issues and means we don't have to
// store a map of net ID to trade index on our end. // store a map of net ID to trade index on our end.
@ -143,7 +147,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
} }
@Override @Override
public ItemStackResponsePacket.Response translateAutoCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateAutoCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
// 1.18.10 update - seems impossible to call without consoles/controller input // 1.18.10 update - seems impossible to call without consoles/controller input
// We set the net ID to the trade index + 1. This doesn't appear to cause issues and means we don't have to // We set the net ID to the trade index + 1. This doesn't appear to cause issues and means we don't have to
// store a map of net ID to trade index on our end. // store a map of net ID to trade index on our end.
@ -151,7 +155,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator {
return handleTrade(session, inventory, request, tradeChoice); return handleTrade(session, inventory, request, tradeChoice);
} }
private ItemStackResponsePacket.Response handleTrade(GeyserSession session, Inventory inventory, ItemStackRequest request, int tradeChoice) { private ItemStackResponse handleTrade(GeyserSession session, Inventory inventory, ItemStackRequest request, int tradeChoice) {
ServerboundSelectTradePacket packet = new ServerboundSelectTradePacket(tradeChoice); ServerboundSelectTradePacket packet = new ServerboundSelectTradePacket(tradeChoice);
session.sendDownstreamPacket(packet); session.sendDownstreamPacket(packet);

Datei anzeigen

@ -30,15 +30,28 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType; import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.cloudburstmc.protocol.bedrock.data.inventory.*;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.*;
import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
import it.unimi.dsi.fastutil.ints.IntIterator; import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import org.geysermc.geyser.inventory.*; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftCreativeStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.DestroyStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.DropStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.SwapStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.TransferStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory;
import org.geysermc.geyser.inventory.SlotType;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.skin.FakeHeadProvider; import org.geysermc.geyser.skin.FakeHeadProvider;
import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.GeyserLocale;
@ -226,7 +239,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
} }
@Override @Override
public ItemStackResponsePacket.Response translateRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { public ItemStackResponse translateRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
if (session.getGameMode() != GameMode.CREATIVE) { if (session.getGameMode() != GameMode.CREATIVE) {
return super.translateRequest(session, inventory, request); return super.translateRequest(session, inventory, request);
} }
@ -386,7 +399,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
} }
@Override @Override
protected ItemStackResponsePacket.Response translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { protected ItemStackResponse translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
ItemStack javaCreativeItem = null; ItemStack javaCreativeItem = null;
IntSet affectedSlots = new IntOpenHashSet(); IntSet affectedSlots = new IntOpenHashSet();
CraftState craftState = CraftState.START; CraftState craftState = CraftState.START;

Datei anzeigen

@ -30,12 +30,17 @@ import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData; import org.cloudburstmc.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType; import org.cloudburstmc.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket; import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory;
import org.geysermc.geyser.inventory.SlotType;
import org.geysermc.geyser.inventory.StonecutterContainer;
import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -51,7 +56,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
} }
@Override @Override
protected ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { protected ItemStackResponse translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
// Guarded by shouldHandleRequestFirst // Guarded by shouldHandleRequestFirst
CraftRecipeStackRequestActionData data = (CraftRecipeStackRequestActionData) request.getActions()[0]; CraftRecipeStackRequestActionData data = (CraftRecipeStackRequestActionData) request.getActions()[0];

Datei anzeigen

@ -144,7 +144,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
// But send a container close packet because we aren't destroying the original. // But send a container close packet because we aren't destroying the original.
ContainerClosePacket packet = new ContainerClosePacket(); ContainerClosePacket packet = new ContainerClosePacket();
packet.setId((byte) inventory.getBedrockId()); packet.setId((byte) inventory.getBedrockId());
packet.setUnknownBool0(true); //TODO needs to be changed in Protocol to "server-side" or something packet.setServerInitiated(true);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
return; return;
} }

Datei anzeigen

@ -51,7 +51,7 @@ public class PotionTranslator extends ItemTranslator {
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
if (potion != null) { if (potion != null) {
return ItemData.builder() return ItemData.builder()
.id(mapping.getBedrockDefinition()) .definition(mapping.getBedrockDefinition())
.damage(potion.getBedrockId()) .damage(potion.getBedrockId())
.count(itemStack.getAmount()) .count(itemStack.getAmount())
.tag(translateNbtToBedrock(itemStack.getNbt())); .tag(translateNbtToBedrock(itemStack.getNbt()));

Datei anzeigen

@ -57,7 +57,7 @@ public class TippedArrowTranslator extends ItemTranslator {
TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue()); TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue());
if (tippedArrowPotion != null) { if (tippedArrowPotion != null) {
return ItemData.builder() return ItemData.builder()
.id(mapping.getBedrockDefinition()) .definition(mapping.getBedrockDefinition())
.damage(tippedArrowPotion.getBedrockId()) .damage(tippedArrowPotion.getBedrockId())
.count(itemStack.getAmount()) .count(itemStack.getAmount())
.tag(translateNbtToBedrock(itemStack.getNbt())); .tag(translateNbtToBedrock(itemStack.getNbt()));

Datei anzeigen

@ -598,7 +598,7 @@ public class PistonBlockEntity {
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
updateBlockPacket.setBlockPosition(newPos); updateBlockPacket.setBlockPosition(newPos);
updateBlockPacket.setRuntimeId(session.getBlockMappings().getBedrockMovingBlock()); updateBlockPacket.setRuntimeId(session.getBlockMappings().getBedrockMovingBlock().getRuntimeId());
updateBlockPacket.setDataLayer(0); updateBlockPacket.setDataLayer(0);
session.sendUpstreamPacket(updateBlockPacket); session.sendUpstreamPacket(updateBlockPacket);
// Update moving block with correct details // Update moving block with correct details

Datei anzeigen

@ -287,10 +287,10 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
int blockState = session.getGeyser().getWorldManager().getBlockAt(session, packet.getBlockPosition()); int blockState = session.getGeyser().getWorldManager().getBlockAt(session, packet.getBlockPosition());
// Otherwise boats will not be able to be placed in survival and buckets, lily pads, frogspawn, and glass bottles won't work on mobile // Otherwise boats will not be able to be placed in survival and buckets, lily pads, frogspawn, and glass bottles won't work on mobile
if (session.getItemMappings().getBoats().contains(definition) || if (session.getItemMappings().getBoats().contains(definition) ||
definition == session.getItemMappings().getStoredItems().lilyPad() || definition == session.getItemMappings().getStoredItems().lilyPad().getBedrockDefinition() ||
definition == session.getItemMappings().getStoredItems().frogspawn()) { definition == session.getItemMappings().getStoredItems().frogspawn().getBedrockDefinition()) {
useItem(session, packet, blockState); useItem(session, packet, blockState);
} else if (definition == session.getItemMappings().getStoredItems().glassBottle()) { } else if (definition == session.getItemMappings().getStoredItems().glassBottle().getBedrockDefinition()) {
if (!session.isSneaking() && BlockStateValues.isCauldron(blockState) && !BlockStateValues.isNonWaterCauldron(blockState)) { if (!session.isSneaking() && BlockStateValues.isCauldron(blockState) && !BlockStateValues.isNonWaterCauldron(blockState)) {
// ServerboundUseItemPacket is not sent for water cauldrons and glass bottles // ServerboundUseItemPacket is not sent for water cauldrons and glass bottles
return; return;
@ -350,7 +350,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
} else if (session.getItemMappings().getSpawnEggs().contains(packet.getItemInHand().getDefinition())) { } else if (session.getItemMappings().getSpawnEggs().contains(packet.getItemInHand().getDefinition())) {
// Handled in case 0 // Handled in case 0
break; break;
} else if (packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().glassBottle()) { } else if (packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().glassBottle().getBedrockDefinition()) {
// Handled in case 0 // Handled in case 0
break; break;
} }
@ -574,8 +574,8 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
int heldItemSlot = playerInventory.getOffsetForHotbar(packet.getHotbarSlot()); int heldItemSlot = playerInventory.getOffsetForHotbar(packet.getHotbarSlot());
InventoryTranslator.PLAYER_INVENTORY_TRANSLATOR.updateSlot(session, playerInventory, heldItemSlot); InventoryTranslator.PLAYER_INVENTORY_TRANSLATOR.updateSlot(session, playerInventory, heldItemSlot);
if (playerInventory.getItem(heldItemSlot).getAmount() > 1) { if (playerInventory.getItem(heldItemSlot).getAmount() > 1) {
if (packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().bucket() || if (packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().bucket().getBedrockDefinition() ||
packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().glassBottle()) { packet.getItemInHand().getDefinition() == session.getItemMappings().getStoredItems().glassBottle().getBedrockDefinition()) {
// Using a stack of buckets or glass bottles will result in an item being added to the first empty slot. // Using a stack of buckets or glass bottles will result in an item being added to the first empty slot.
// We need to revert the item in case the interaction fails. The order goes from left to right in the // We need to revert the item in case the interaction fails. The order goes from left to right in the
// hotbar. Then left to right and top to bottom in the inventory. // hotbar. Then left to right and top to bottom in the inventory.

Datei anzeigen

@ -26,18 +26,26 @@
package org.geysermc.geyser.translator.protocol.bedrock.entity.player; package org.geysermc.geyser.translator.protocol.bedrock.entity.player;
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
import com.github.steveice10.mc.protocol.data.game.entity.player.*; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket;
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.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.PlayerActionType; import org.cloudburstmc.protocol.bedrock.data.PlayerActionType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.packet.*; import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlayStatusPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket;
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.entity.type.ItemFrameEntity;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
@ -141,7 +149,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
if (session.getGameMode() != GameMode.CREATIVE) { if (session.getGameMode() != GameMode.CREATIVE) {
int blockState = session.getGeyser().getWorldManager().getBlockAt(session, vector); int blockState = session.getGeyser().getWorldManager().getBlockAt(session, vector);
LevelEventPacket startBreak = new LevelEventPacket(); LevelEventPacket startBreak = new LevelEventPacket();
startBreak.setType(LevelEventType.BLOCK_START_BREAK); startBreak.setType(LevelEvent.BLOCK_START_BREAK);
startBreak.setPosition(vector.toFloat()); startBreak.setPosition(vector.toFloat());
double breakTime = BlockUtils.getSessionBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(blockState)) * 20; double breakTime = BlockUtils.getSessionBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(blockState)) * 20;
startBreak.setData((int) (65535 / breakTime)); startBreak.setData((int) (65535 / breakTime));
@ -177,14 +185,14 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
Vector3f vectorFloat = vector.toFloat(); Vector3f vectorFloat = vector.toFloat();
LevelEventPacket continueBreakPacket = new LevelEventPacket(); LevelEventPacket continueBreakPacket = new LevelEventPacket();
continueBreakPacket.setType(LevelEventType.PARTICLE_CRACK_BLOCK); continueBreakPacket.setType(LevelEvent.PARTICLE_CRACK_BLOCK);
continueBreakPacket.setData((session.getBlockMappings().getBedrockBlockId(breakingBlock)) | (packet.getFace() << 24)); continueBreakPacket.setData((session.getBlockMappings().getBedrockBlockId(breakingBlock)) | (packet.getFace() << 24));
continueBreakPacket.setPosition(vectorFloat); continueBreakPacket.setPosition(vectorFloat);
session.sendUpstreamPacket(continueBreakPacket); session.sendUpstreamPacket(continueBreakPacket);
// Update the break time in the event that player conditions changed (jumping, effects applied) // Update the break time in the event that player conditions changed (jumping, effects applied)
LevelEventPacket updateBreak = new LevelEventPacket(); LevelEventPacket updateBreak = new LevelEventPacket();
updateBreak.setType(LevelEventType.BLOCK_UPDATE_BREAK); updateBreak.setType(LevelEvent.BLOCK_UPDATE_BREAK);
updateBreak.setPosition(vectorFloat); updateBreak.setPosition(vectorFloat);
double breakTime = BlockUtils.getSessionBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(breakingBlock)) * 20; double breakTime = BlockUtils.getSessionBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(breakingBlock)) * 20;
updateBreak.setData((int) (65535 / breakTime)); updateBreak.setData((int) (65535 / breakTime));
@ -206,7 +214,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
ServerboundPlayerActionPacket abortBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.CANCEL_DIGGING, vector, Direction.DOWN, 0); ServerboundPlayerActionPacket abortBreakingPacket = new ServerboundPlayerActionPacket(PlayerAction.CANCEL_DIGGING, vector, Direction.DOWN, 0);
session.sendDownstreamPacket(abortBreakingPacket); session.sendDownstreamPacket(abortBreakingPacket);
LevelEventPacket stopBreak = new LevelEventPacket(); LevelEventPacket stopBreak = new LevelEventPacket();
stopBreak.setType(LevelEventType.BLOCK_STOP_BREAK); stopBreak.setType(LevelEvent.BLOCK_STOP_BREAK);
stopBreak.setPosition(vector.toFloat()); stopBreak.setPosition(vector.toFloat());
stopBreak.setData(0); stopBreak.setData(0);
session.setBreakingBlock(-1); session.setBreakingBlock(-1);

Datei anzeigen

@ -88,7 +88,7 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
if (session.getMouseoverEntity() != null) { if (session.getMouseoverEntity() != null) {
// No interactive tag should be sent // No interactive tag should be sent
session.setMouseoverEntity(null); session.setMouseoverEntity(null);
session.getPlayerEntity().getDirtyMetadata().put(EntityDataTypes.INTERACTIVE_TAG, ""); session.getPlayerEntity().getDirtyMetadata().put(EntityDataTypes.INTERACT_TEXT, "");
session.getPlayerEntity().updateBedrockMetadata(); session.getPlayerEntity().updateBedrockMetadata();
} }
} }

Datei anzeigen

@ -31,6 +31,7 @@ import com.github.steveice10.mc.protocol.data.game.command.properties.ResourcePr
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType; import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCommandsPacket;
import org.cloudburstmc.protocol.bedrock.data.command.CommandData; import org.cloudburstmc.protocol.bedrock.data.command.CommandData;
import org.cloudburstmc.protocol.bedrock.data.command.CommandEnumConstraint;
import org.cloudburstmc.protocol.bedrock.data.command.CommandEnumData; import org.cloudburstmc.protocol.bedrock.data.command.CommandEnumData;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParam; import org.cloudburstmc.protocol.bedrock.data.command.CommandParam;
import org.cloudburstmc.protocol.bedrock.data.command.CommandParamData; import org.cloudburstmc.protocol.bedrock.data.command.CommandParamData;
@ -156,14 +157,20 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
} }
// The command flags, not sure what these do apart from break things // The command flags, not sure what these do apart from break things
List<CommandData.Flag> flags = Collections.emptyList(); Set<CommandData.Flag> flags = Set.of();
// Loop through all the found commands // Loop through all the found commands
for (Map.Entry<BedrockCommandInfo, Set<String>> entry : commands.entrySet()) { for (Map.Entry<BedrockCommandInfo, Set<String>> entry : commands.entrySet()) {
String commandName = entry.getValue().iterator().next(); // We know this has a value String commandName = entry.getValue().iterator().next(); // We know this has a value
LinkedHashMap<String, Set<CommandEnumConstraint>> values = new LinkedHashMap<>();
// Is this right?
for (String s : entry.getValue()) {
values.put(s, Set.of(CommandEnumConstraint.ALLOW_ALIASES));
}
// Create a basic alias // Create a basic alias
CommandEnumData aliases = new CommandEnumData(commandName + "Aliases", entry.getValue().toArray(new String[0]), false); CommandEnumData aliases = new CommandEnumData(commandName + "Aliases", values, false);
// Build the completed command and add it to the final list // Build the completed command and add it to the final list
CommandData data = new CommandData(commandName, entry.getKey().description(), flags, (byte) 0, aliases, entry.getKey().paramData()); CommandData data = new CommandData(commandName, entry.getKey().description(), flags, (byte) 0, aliases, entry.getKey().paramData());
@ -298,25 +305,41 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
// Check to make sure all descending nodes of this command are compatible - otherwise, create a new overload // Check to make sure all descending nodes of this command are compatible - otherwise, create a new overload
if (isCompatible(allNodes, enumParamInfo.getParamNode(), paramNode)) { if (isCompatible(allNodes, enumParamInfo.getParamNode(), paramNode)) {
foundCompatible = true; foundCompatible = true;
// TODO: Check this
// Extend the current list of enum values // Extend the current list of enum values
String[] enumOptions = Arrays.copyOf(enumParamInfo.getParamData().getEnumData().getValues(), enumParamInfo.getParamData().getEnumData().getValues().length + 1); // String[] enumOptions = Arrays.copyOf(enumParamInfo.getParamData().getEnumData().getValues(), enumParamInfo.getParamData().getEnumData().getValues().size() + 1);
enumOptions[enumOptions.length - 1] = paramNode.getName(); // enumOptions[enumOptions.length - 1] = paramNode.getName();
LinkedHashMap<String, Set<CommandEnumConstraint>> values = (LinkedHashMap<String, Set<CommandEnumConstraint>>) enumParamInfo.getParamData().getEnumData().getValues().clone();
values.put(paramNode.getName(), Set.of());
// Re-create the command using the updated values // Re-create the command using the updated values
CommandEnumData enumData = new CommandEnumData(enumParamInfo.getParamData().getEnumData().getName(), enumOptions, false); CommandEnumData enumData = new CommandEnumData(enumParamInfo.getParamData().getEnumData().getName(), values, false);
children.set(i, new ParamInfo(enumParamInfo.getParamNode(), new CommandParamData(enumParamInfo.getParamData().getName(), this.paramNode.isExecutable(), enumData, null, null, Collections.emptyList()))); CommandParamData commandParamData = new CommandParamData();
commandParamData.setName(enumParamInfo.getParamData().getName());
commandParamData.setOptional(this.paramNode.isExecutable());
commandParamData.setEnumData(enumData);
children.set(i, new ParamInfo(enumParamInfo.getParamNode(), commandParamData));
break; break;
} }
} }
if (!foundCompatible) { if (!foundCompatible) {
// Create a new subcommand with this exact type // Create a new subcommand with this exact type
CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[]{paramNode.getName()}, false); LinkedHashMap<String, Set<CommandEnumConstraint>> map = new LinkedHashMap<>();
map.put(paramNode.getName(), Set.of());
CommandEnumData enumData = new CommandEnumData(paramNode.getName(), map, false);
// On setting optional: // On setting optional:
// isExecutable is defined as a node "constitutes a valid command." // isExecutable is defined as a node "constitutes a valid command."
// Therefore, any children of the parameter must simply be optional. // Therefore, any children of the parameter must simply be optional.
children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), this.paramNode.isExecutable(), enumData, null, null, Collections.emptyList()))); CommandParamData commandParamData = new CommandParamData();
commandParamData.setName(paramNode.getName());
commandParamData.setOptional(this.paramNode.isExecutable());
commandParamData.setEnumData(enumData);
children.add(new ParamInfo(paramNode, commandParamData));
} }
} else { } else {
// Put the non-enum param into the list // Put the non-enum param into the list
@ -325,7 +348,12 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
CommandParam type = null; CommandParam type = null;
boolean optional = this.paramNode.isExecutable(); boolean optional = this.paramNode.isExecutable();
if (mappedType instanceof String[]) { if (mappedType instanceof String[]) {
enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(Locale.ROOT), (String[]) mappedType, false); LinkedHashMap<String, Set<CommandEnumConstraint>> map = new LinkedHashMap<>();
for (String s : (String[]) mappedType) {
map.put(s, Set.of());
}
enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(Locale.ROOT), map, false);
} else { } else {
type = (CommandParam) mappedType; type = (CommandParam) mappedType;
// Bedrock throws a fit if an optional message comes after a string or target // Bedrock throws a fit if an optional message comes after a string or target
@ -337,7 +365,13 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
// IF enumData != null: // IF enumData != null:
// In game, this will show up like <paramNode.getName(): enumData.getName()> // In game, this will show up like <paramNode.getName(): enumData.getName()>
// So if paramNode.getName() == "value" and enumData.getName() == "bool": <value: bool> // So if paramNode.getName() == "value" and enumData.getName() == "bool": <value: bool>
children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), optional, enumData, type, null, Collections.emptyList()))); CommandParamData commandParamData = new CommandParamData();
commandParamData.setName(paramNode.getName());
commandParamData.setOptional(optional);
commandParamData.setEnumData(enumData);
commandParamData.setType(type);
children.add(new ParamInfo(paramNode, commandParamData));
} }
} }

Datei anzeigen

@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.protocol.java;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRespawnPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRespawnPacket;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket;
@ -64,7 +65,7 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
if (session.isRaining()) { if (session.isRaining()) {
LevelEventPacket stopRainPacket = new LevelEventPacket(); LevelEventPacket stopRainPacket = new LevelEventPacket();
stopRainPacket.setType(LevelEventType.STOP_RAINING); stopRainPacket.setType(LevelEvent.STOP_RAINING);
stopRainPacket.setData(0); stopRainPacket.setData(0);
stopRainPacket.setPosition(Vector3f.ZERO); stopRainPacket.setPosition(Vector3f.ZERO);
session.sendUpstreamPacket(stopRainPacket); session.sendUpstreamPacket(stopRainPacket);
@ -73,7 +74,7 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
if (session.isThunder()) { if (session.isThunder()) {
LevelEventPacket stopThunderPacket = new LevelEventPacket(); LevelEventPacket stopThunderPacket = new LevelEventPacket();
stopThunderPacket.setType(LevelEventType.STOP_THUNDERSTORM); stopThunderPacket.setType(LevelEvent.STOP_THUNDERSTORM);
stopThunderPacket.setData(0); stopThunderPacket.setData(0);
stopThunderPacket.setPosition(Vector3f.ZERO); stopThunderPacket.setPosition(Vector3f.ZERO);
session.sendUpstreamPacket(stopThunderPacket); session.sendUpstreamPacket(stopThunderPacket);

Datei anzeigen

@ -34,14 +34,19 @@ import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeDa
import com.github.steveice10.mc.protocol.data.game.recipe.data.SmithingRecipeData; import com.github.steveice10.mc.protocol.data.game.recipe.data.SmithingRecipeData;
import com.github.steveice10.mc.protocol.data.game.recipe.data.StoneCuttingRecipeData; import com.github.steveice10.mc.protocol.data.game.recipe.data.StoneCuttingRecipeData;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.inventory.CraftingData; import org.cloudburstmc.protocol.bedrock.data.inventory.CraftingData;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.DefaultDescriptor; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.DefaultDescriptor;
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket; import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket;
import it.unimi.dsi.fastutil.ints.*;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import org.geysermc.geyser.inventory.recipe.GeyserRecipe; import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe; import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe; import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe;
@ -54,7 +59,16 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.geyser.util.InventoryUtils;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.geysermc.geyser.util.InventoryUtils.LAST_RECIPE_NET_ID; import static org.geysermc.geyser.util.InventoryUtils.LAST_RECIPE_NET_ID;
@ -218,7 +232,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
Ingredient ingredient = ingredients[i]; Ingredient ingredient = ingredients[i];
Map<GroupedItem, List<ItemDescriptorWithCount>> groupedByIds = Arrays.stream(ingredient.getOptions()) Map<GroupedItem, List<ItemDescriptorWithCount>> groupedByIds = Arrays.stream(ingredient.getOptions())
.map(item -> ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, item))) .map(item -> ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, item)))
.collect(Collectors.groupingBy(item -> item == ItemDescriptorWithCount.EMPTY ? new GroupedItem(0, 0) : new GroupedItem(((DefaultDescriptor) item.getDescriptor()).getItemId(), item.getCount()))); .collect(Collectors.groupingBy(item -> item == ItemDescriptorWithCount.EMPTY ? new GroupedItem(ItemDefinition.AIR, 0) : new GroupedItem(((DefaultDescriptor) item.getDescriptor()).getItemId(), item.getCount())));
Set<ItemDescriptorWithCount> optionSet = new HashSet<>(groupedByIds.size()); Set<ItemDescriptorWithCount> optionSet = new HashSet<>(groupedByIds.size());
for (Map.Entry<GroupedItem, List<ItemDescriptorWithCount>> entry : groupedByIds.entrySet()) { for (Map.Entry<GroupedItem, List<ItemDescriptorWithCount>> entry : groupedByIds.entrySet()) {
if (entry.getValue().size() > 1) { if (entry.getValue().size() > 1) {
@ -233,7 +247,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
if (entry.getValue().size() < idCount) { if (entry.getValue().size() < idCount) {
optionSet.addAll(entry.getValue()); optionSet.addAll(entry.getValue());
} else { } else {
optionSet.add(groupedItem.id == 0 ? ItemDescriptorWithCount.EMPTY : new ItemDescriptorWithCount(new DefaultDescriptor(groupedItem.id, Short.MAX_VALUE), groupedItem.count)); optionSet.add(groupedItem.id == ItemDefinition.AIR ? ItemDescriptorWithCount.EMPTY : new ItemDescriptorWithCount(new DefaultDescriptor(groupedItem.id, Short.MAX_VALUE), groupedItem.count));
} }
} else { } else {
ItemDescriptorWithCount item = entry.getValue().get(0); ItemDescriptorWithCount item = entry.getValue().get(0);
@ -281,7 +295,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
@EqualsAndHashCode @EqualsAndHashCode
@AllArgsConstructor @AllArgsConstructor
private static class GroupedItem { private static class GroupedItem {
int id; ItemDefinition id;
int count; int count;
} }
} }

Datei anzeigen

@ -98,7 +98,7 @@ public class JavaSetPassengersTranslator extends PacketTranslator<ClientboundSet
switch (entity.getDefinition().entityType()) { switch (entity.getDefinition().entityType()) {
case HORSE, SKELETON_HORSE, DONKEY, MULE, RAVAGER -> { case HORSE, SKELETON_HORSE, DONKEY, MULE, RAVAGER -> {
entity.getDirtyMetadata().put(EntityDataTypes.RIDER_MAX_ROTATION, 181.0f); entity.getDirtyMetadata().put(EntityDataTypes.SEAT_ROTATION_OFFSET, 181.0f);
entity.updateBedrockMetadata(); entity.updateBedrockMetadata();
} }
} }

Datei anzeigen

@ -26,6 +26,7 @@
package org.geysermc.geyser.translator.protocol.java.entity; package org.geysermc.geyser.translator.protocol.java.entity;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundTakeItemEntityPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.ClientboundTakeItemEntityPacket;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.TakeItemEntityPacket; import org.cloudburstmc.protocol.bedrock.packet.TakeItemEntityPacket;
@ -54,7 +55,7 @@ public class JavaTakeItemEntityTranslator extends PacketTranslator<ClientboundTa
if (collectedEntity instanceof ExpOrbEntity) { if (collectedEntity instanceof ExpOrbEntity) {
// Player just picked up an experience orb // Player just picked up an experience orb
LevelEventPacket xpPacket = new LevelEventPacket(); LevelEventPacket xpPacket = new LevelEventPacket();
xpPacket.setType(LevelEventType.SOUND_EXPERIENCE_ORB_PICKUP); xpPacket.setType(LevelEvent.SOUND_EXPERIENCE_ORB_PICKUP);
xpPacket.setPosition(collectedEntity.getPosition()); xpPacket.setPosition(collectedEntity.getPosition());
xpPacket.setData(0); xpPacket.setData(0);
session.sendUpstreamPacket(xpPacket); session.sendUpstreamPacket(xpPacket);

Datei anzeigen

@ -75,7 +75,7 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
Entity villager = merchantInventory.getVillager(); Entity villager = merchantInventory.getVillager();
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);
villager.getDirtyMetadata().put(EntityDataTypes.TRADE_XP, packet.getExperience()); villager.getDirtyMetadata().put(EntityDataTypes.TRADE_EXPERIENCE, packet.getExperience());
villager.updateBedrockMetadata(); villager.updateBedrockMetadata();
// Construct the packet that opens the trading window // Construct the packet that opens the trading window
@ -170,7 +170,7 @@ public class JavaMerchantOffersTranslator extends PacketTranslator<ClientboundMe
private static NbtMap getItemTag(GeyserSession session, ItemStack stack, ItemMapping mapping, int count) { private static NbtMap getItemTag(GeyserSession session, ItemStack stack, ItemMapping mapping, int count) {
ItemData itemData = ItemTranslator.translateToBedrock(session, stack); ItemData itemData = ItemTranslator.translateToBedrock(session, stack);
String customIdentifier = session.getItemMappings().getCustomIdMappings().get(itemData.getId()); String customIdentifier = session.getItemMappings().getCustomIdMappings().get(itemData.getDefinition().getRuntimeId());
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
builder.putByte("Count", (byte) count); builder.putByte("Count", (byte) count);

Datei anzeigen

@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.protocol.java.level;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockDestructionPacket;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
@ -45,7 +46,7 @@ public class JavaBlockDestructionTranslator extends PacketTranslator<Clientbound
int breakTime = (int) (65535 / Math.ceil(BlockUtils.getBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(state), ItemMapping.AIR, new CompoundTag(""), false) * 20)); int breakTime = (int) (65535 / Math.ceil(BlockUtils.getBreakTime(session, BlockRegistries.JAVA_BLOCKS.get(state), ItemMapping.AIR, new CompoundTag(""), false) * 20));
LevelEventPacket levelEventPacket = new LevelEventPacket(); LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(packet.getPosition().toFloat()); levelEventPacket.setPosition(packet.getPosition().toFloat());
levelEventPacket.setType(LevelEventType.BLOCK_START_BREAK); levelEventPacket.setType(LevelEvent.BLOCK_START_BREAK);
switch (packet.getStage()) { switch (packet.getStage()) {
case STAGE_1 -> levelEventPacket.setData(breakTime); case STAGE_1 -> levelEventPacket.setData(breakTime);
@ -59,7 +60,7 @@ public class JavaBlockDestructionTranslator extends PacketTranslator<Clientbound
case STAGE_9 -> levelEventPacket.setData(breakTime * 9); case STAGE_9 -> levelEventPacket.setData(breakTime * 9);
case STAGE_10 -> levelEventPacket.setData(breakTime * 10); case STAGE_10 -> levelEventPacket.setData(breakTime * 10);
case RESET -> { case RESET -> {
levelEventPacket.setType(LevelEventType.BLOCK_STOP_BREAK); levelEventPacket.setType(LevelEvent.BLOCK_STOP_BREAK);
levelEventPacket.setData(0); levelEventPacket.setData(0);
} }
} }

Datei anzeigen

@ -43,7 +43,7 @@ public class JavaCooldownTranslator extends PacketTranslator<ClientboundCooldown
// Not every item, as of 1.19, appears to be server-driven. Just these two. // Not every item, as of 1.19, appears to be server-driven. Just these two.
// Use a map here if it gets too big. // Use a map here if it gets too big.
String cooldownCategory; String cooldownCategory;
if (itemId == itemMappings.goatHorn()) { if (itemId == itemMappings.goatHorn().getJavaId()) {
cooldownCategory = "goat_horn"; cooldownCategory = "goat_horn";
} else if (itemId == itemMappings.shield().getJavaId()) { } else if (itemId == itemMappings.shield().getJavaId()) {
cooldownCategory = "shield"; cooldownCategory = "shield";

Datei anzeigen

@ -47,7 +47,7 @@ public class JavaExplodeTranslator extends PacketTranslator<ClientboundExplodePa
@Override @Override
public void translate(GeyserSession session, ClientboundExplodePacket packet) { public void translate(GeyserSession session, ClientboundExplodePacket packet) {
LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket(); LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket();
levelEventPacket.setEventId(2026/*LevelEventType.PARTICLE_BLOCK_EXPLOSION*/); levelEventPacket.setEventId(2026/*LevelEvent.PARTICLE_BLOCK_EXPLOSION*/);
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
builder.putFloat("originX", packet.getX()); builder.putFloat("originX", packet.getX());
builder.putFloat("originY", packet.getY()); builder.putFloat("originY", packet.getY());

Datei anzeigen

@ -35,6 +35,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.Clientb
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.GameRuleData; import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
import org.cloudburstmc.protocol.bedrock.packet.*; import org.cloudburstmc.protocol.bedrock.packet.*;
@ -55,7 +56,7 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
switch (packet.getNotification()) { switch (packet.getNotification()) {
case START_RAIN: case START_RAIN:
LevelEventPacket startRainPacket = new LevelEventPacket(); LevelEventPacket startRainPacket = new LevelEventPacket();
startRainPacket.setType(LevelEventType.START_RAINING); startRainPacket.setType(LevelEvent.START_RAINING);
startRainPacket.setData(Integer.MAX_VALUE); startRainPacket.setData(Integer.MAX_VALUE);
startRainPacket.setPosition(Vector3f.ZERO); startRainPacket.setPosition(Vector3f.ZERO);
session.sendUpstreamPacket(startRainPacket); session.sendUpstreamPacket(startRainPacket);
@ -63,7 +64,7 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
break; break;
case STOP_RAIN: case STOP_RAIN:
LevelEventPacket stopRainPacket = new LevelEventPacket(); LevelEventPacket stopRainPacket = new LevelEventPacket();
stopRainPacket.setType(LevelEventType.STOP_RAINING); stopRainPacket.setType(LevelEvent.STOP_RAINING);
stopRainPacket.setData(0); stopRainPacket.setData(0);
stopRainPacket.setPosition(Vector3f.ZERO); stopRainPacket.setPosition(Vector3f.ZERO);
session.sendUpstreamPacket(stopRainPacket); session.sendUpstreamPacket(stopRainPacket);
@ -78,7 +79,7 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
// Java sends the rain level. Bedrock doesn't care, so we don't care if it's already raining. // Java sends the rain level. Bedrock doesn't care, so we don't care if it's already raining.
if (isCurrentlyRaining != session.isRaining()) { if (isCurrentlyRaining != session.isRaining()) {
LevelEventPacket changeRainPacket = new LevelEventPacket(); LevelEventPacket changeRainPacket = new LevelEventPacket();
changeRainPacket.setType(isCurrentlyRaining ? LevelEventType.START_RAINING : LevelEventType.STOP_RAINING); changeRainPacket.setType(isCurrentlyRaining ? LevelEvent.START_RAINING : LevelEvent.STOP_RAINING);
changeRainPacket.setData(Integer.MAX_VALUE); // Dunno what this does; used to be implemented with ThreadLocalRandom changeRainPacket.setData(Integer.MAX_VALUE); // Dunno what this does; used to be implemented with ThreadLocalRandom
changeRainPacket.setPosition(Vector3f.ZERO); changeRainPacket.setPosition(Vector3f.ZERO);
session.sendUpstreamPacket(changeRainPacket); session.sendUpstreamPacket(changeRainPacket);
@ -91,7 +92,7 @@ public class JavaGameEventTranslator extends PacketTranslator<ClientboundGameEve
boolean isCurrentlyThundering = thunderValue.getStrength() > 0f; boolean isCurrentlyThundering = thunderValue.getStrength() > 0f;
if (isCurrentlyThundering != session.isThunder()) { if (isCurrentlyThundering != session.isThunder()) {
LevelEventPacket changeThunderPacket = new LevelEventPacket(); LevelEventPacket changeThunderPacket = new LevelEventPacket();
changeThunderPacket.setType(isCurrentlyThundering ? LevelEventType.START_THUNDERSTORM : LevelEventType.STOP_THUNDERSTORM); changeThunderPacket.setType(isCurrentlyThundering ? LevelEvent.START_THUNDERSTORM : LevelEvent.STOP_THUNDERSTORM);
changeThunderPacket.setData(Integer.MAX_VALUE); changeThunderPacket.setData(Integer.MAX_VALUE);
changeThunderPacket.setPosition(Vector3f.ZERO); changeThunderPacket.setPosition(Vector3f.ZERO);
session.sendUpstreamPacket(changeThunderPacket); session.sendUpstreamPacket(changeThunderPacket);

Datei anzeigen

@ -128,7 +128,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
if (javaPalette instanceof GlobalPalette) { if (javaPalette instanceof GlobalPalette) {
// As this is the global palette, simply iterate through the whole chunk section once // As this is the global palette, simply iterate through the whole chunk section once
GeyserChunkSection section = new GeyserChunkSection(session.getBlockMappings().getBedrockAir()); GeyserChunkSection section = new GeyserChunkSection(session.getBlockMappings().getBedrockAir().getRuntimeId());
for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) { for (int yzx = 0; yzx < BlockStorage.SIZE; yzx++) {
int javaId = javaData.get(yzx); int javaId = javaData.get(yzx);
int bedrockId = session.getBlockMappings().getBedrockBlockId(javaId); int bedrockId = session.getBlockMappings().getBedrockBlockId(javaId);
@ -136,7 +136,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
section.getBlockStorageArray()[0].setFullBlock(xzy, bedrockId); section.getBlockStorageArray()[0].setFullBlock(xzy, bedrockId);
if (BlockRegistries.WATERLOGGED.get().contains(javaId)) { if (BlockRegistries.WATERLOGGED.get().contains(javaId)) {
section.getBlockStorageArray()[1].setFullBlock(xzy, session.getBlockMappings().getBedrockWater()); section.getBlockStorageArray()[1].setFullBlock(xzy, session.getBlockMappings().getBedrockWater().getRuntimeId());
} }
// Check if block is piston or flower to see if we'll need to create additional block entities, as they're only block entities in Bedrock // Check if block is piston or flower to see if we'll need to create additional block entities, as they're only block entities in Bedrock
@ -230,8 +230,8 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
// V1 palette // V1 palette
IntList layer1Palette = IntList.of( IntList layer1Palette = IntList.of(
session.getBlockMappings().getBedrockAir(), // Air - see BlockStorage's constructor for more information session.getBlockMappings().getBedrockAir().getRuntimeId(), // Air - see BlockStorage's constructor for more information
session.getBlockMappings().getBedrockWater()); session.getBlockMappings().getBedrockWater().getRuntimeId());
layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) }; layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) };
} }

Datei anzeigen

@ -98,7 +98,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
effectPacket.setData(0); effectPacket.setData(0);
switch (packet.getEvent()) { switch (packet.getEvent()) {
case COMPOSTER -> { case COMPOSTER -> {
effectPacket.setType(LevelEventType.PARTICLE_CROP_GROWTH); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_CROP_GROWTH);
ComposterEventData composterEventData = (ComposterEventData) packet.getData(); ComposterEventData composterEventData = (ComposterEventData) packet.getData();
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket();
@ -114,7 +114,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
session.sendUpstreamPacket(soundEventPacket); session.sendUpstreamPacket(soundEventPacket);
} }
case BLOCK_LAVA_EXTINGUISH -> { case BLOCK_LAVA_EXTINGUISH -> {
effectPacket.setType(LevelEventType.PARTICLE_EVAPORATE); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE);
effectPacket.setPosition(pos.add(-0.5f, 0.7f, -0.5f)); effectPacket.setPosition(pos.add(-0.5f, 0.7f, -0.5f));
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket();
@ -127,7 +127,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
session.sendUpstreamPacket(soundEventPacket); session.sendUpstreamPacket(soundEventPacket);
} }
case BLOCK_REDSTONE_TORCH_BURNOUT -> { case BLOCK_REDSTONE_TORCH_BURNOUT -> {
effectPacket.setType(LevelEventType.PARTICLE_EVAPORATE); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE);
effectPacket.setPosition(pos.add(-0.5f, 0, -0.5f)); effectPacket.setPosition(pos.add(-0.5f, 0, -0.5f));
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket();
@ -140,7 +140,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
session.sendUpstreamPacket(soundEventPacket); session.sendUpstreamPacket(soundEventPacket);
} }
case BLOCK_END_PORTAL_FRAME_FILL -> { case BLOCK_END_PORTAL_FRAME_FILL -> {
effectPacket.setType(LevelEventType.PARTICLE_EVAPORATE); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE);
effectPacket.setPosition(pos.add(-0.5f, 0.3125f, -0.5f)); effectPacket.setPosition(pos.add(-0.5f, 0.3125f, -0.5f));
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket();
@ -153,7 +153,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
session.sendUpstreamPacket(soundEventPacket); session.sendUpstreamPacket(soundEventPacket);
} }
case SMOKE -> { case SMOKE -> {
effectPacket.setType(LevelEventType.PARTICLE_SHOOT); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SHOOT);
SmokeEventData smokeEventData = (SmokeEventData) packet.getData(); SmokeEventData smokeEventData = (SmokeEventData) packet.getData();
int data = 0; int data = 0;
@ -189,13 +189,13 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
//TODO: Block break particles when under fire //TODO: Block break particles when under fire
case BREAK_BLOCK -> { case BREAK_BLOCK -> {
effectPacket.setType(LevelEventType.PARTICLE_DESTROY_BLOCK); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_DESTROY_BLOCK);
BreakBlockEventData breakBlockEventData = (BreakBlockEventData) packet.getData(); BreakBlockEventData breakBlockEventData = (BreakBlockEventData) packet.getData();
effectPacket.setData(session.getBlockMappings().getBedrockBlockId(breakBlockEventData.getBlockState())); effectPacket.setData(session.getBlockMappings().getBedrockBlockId(breakBlockEventData.getBlockState()));
} }
case BREAK_SPLASH_POTION, BREAK_SPLASH_POTION2 -> { case BREAK_SPLASH_POTION, BREAK_SPLASH_POTION2 -> {
effectPacket.setType(LevelEventType.PARTICLE_POTION_SPLASH); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_POTION_SPLASH);
effectPacket.setPosition(pos.add(0, -0.5f, 0)); effectPacket.setPosition(pos.add(0, -0.5f, 0));
BreakPotionEventData splashPotionData = (BreakPotionEventData) packet.getData(); BreakPotionEventData splashPotionData = (BreakPotionEventData) packet.getData();
@ -210,16 +210,16 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
soundEventPacket.setRelativeVolumeDisabled(false); soundEventPacket.setRelativeVolumeDisabled(false);
session.sendUpstreamPacket(soundEventPacket); session.sendUpstreamPacket(soundEventPacket);
} }
case BREAK_EYE_OF_ENDER -> effectPacket.setType(LevelEventType.PARTICLE_EYE_OF_ENDER_DEATH); case BREAK_EYE_OF_ENDER -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EYE_OF_ENDER_DEATH);
case MOB_SPAWN -> effectPacket.setType(LevelEventType.PARTICLE_MOB_BLOCK_SPAWN); // TODO: Check, but I don't think I really verified this ever went into effect on Java case MOB_SPAWN -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_MOB_BLOCK_SPAWN); // TODO: Check, but I don't think I really verified this ever went into effect on Java
case BONEMEAL_GROW_WITH_SOUND, BONEMEAL_GROW -> { case BONEMEAL_GROW_WITH_SOUND, BONEMEAL_GROW -> {
effectPacket.setType(packet.getEvent() == LevelEvent.BONEMEAL_GROW ? LevelEventType.PARTICLE_TURTLE_EGG : LevelEventType.PARTICLE_CROP_GROWTH); effectPacket.setType(packet.getEvent() == LevelEvent.BONEMEAL_GROW ? org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_TURTLE_EGG : org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_CROP_GROWTH);
BonemealGrowEventData growEventData = (BonemealGrowEventData) packet.getData(); BonemealGrowEventData growEventData = (BonemealGrowEventData) packet.getData();
effectPacket.setData(growEventData.getParticleCount()); effectPacket.setData(growEventData.getParticleCount());
} }
case ENDERDRAGON_FIREBALL_EXPLODE -> { case ENDERDRAGON_FIREBALL_EXPLODE -> {
effectPacket.setType(LevelEventType.PARTICLE_EYE_OF_ENDER_DEATH); // TODO effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EYE_OF_ENDER_DEATH); // TODO
DragonFireballEventData fireballEventData = (DragonFireballEventData) packet.getData(); DragonFireballEventData fireballEventData = (DragonFireballEventData) packet.getData();
if (fireballEventData == DragonFireballEventData.HAS_SOUND) { if (fireballEventData == DragonFireballEventData.HAS_SOUND) {
@ -234,15 +234,15 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
} }
} }
case EXPLOSION -> { case EXPLOSION -> {
effectPacket.setType(LevelEventType.PARTICLE_GENERIC_SPAWN); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_GENERIC_SPAWN);
effectPacket.setData(61); effectPacket.setData(61);
} }
case EVAPORATE -> { case EVAPORATE -> {
effectPacket.setType(LevelEventType.PARTICLE_EVAPORATE_WATER); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EVAPORATE_WATER);
effectPacket.setPosition(pos.add(-0.5f, 0.5f, -0.5f)); effectPacket.setPosition(pos.add(-0.5f, 0.5f, -0.5f));
} }
case END_GATEWAY_SPAWN -> { case END_GATEWAY_SPAWN -> {
effectPacket.setType(LevelEventType.PARTICLE_EXPLOSION); effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EXPLOSION);
LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket();
soundEventPacket.setSound(SoundEvent.EXPLODE); soundEventPacket.setSound(SoundEvent.EXPLODE);
@ -253,17 +253,17 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
soundEventPacket.setRelativeVolumeDisabled(false); soundEventPacket.setRelativeVolumeDisabled(false);
session.sendUpstreamPacket(soundEventPacket); session.sendUpstreamPacket(soundEventPacket);
} }
case DRIPSTONE_DRIP -> effectPacket.setType(LevelEventType.PARTICLE_DRIPSTONE_DRIP); case DRIPSTONE_DRIP -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_DRIPSTONE_DRIP);
case ELECTRIC_SPARK -> effectPacket.setType(LevelEventType.PARTICLE_ELECTRIC_SPARK); // Matches with a Bedrock server but doesn't seem to match up with Java case ELECTRIC_SPARK -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_ELECTRIC_SPARK); // Matches with a Bedrock server but doesn't seem to match up with Java
case WAX_ON -> effectPacket.setType(LevelEventType.PARTICLE_WAX_ON); case WAX_ON -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_ON);
case WAX_OFF -> effectPacket.setType(LevelEventType.PARTICLE_WAX_OFF); case WAX_OFF -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_WAX_OFF);
case SCRAPE -> effectPacket.setType(LevelEventType.PARTICLE_SCRAPE); case SCRAPE -> effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_SCRAPE);
case SCULK_BLOCK_CHARGE -> { case SCULK_BLOCK_CHARGE -> {
SculkBlockChargeEventData eventData = (SculkBlockChargeEventData) packet.getData(); SculkBlockChargeEventData eventData = (SculkBlockChargeEventData) packet.getData();
LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket(); LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket();
// TODO add SCULK_BLOCK_CHARGE sound // TODO add SCULK_BLOCK_CHARGE sound
if (eventData.getCharge() > 0) { if (eventData.getCharge() > 0) {
levelEventPacket.setEventId(2037/*LevelEventType.SCULK_CHARGE*/); levelEventPacket.setEventId(2037/*LevelEvent.SCULK_CHARGE*/);
levelEventPacket.setTag( levelEventPacket.setTag(
NbtMap.builder() NbtMap.builder()
.putInt("x", packet.getPosition().getX()) .putInt("x", packet.getPosition().getX())
@ -274,7 +274,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
.build() .build()
); );
} else { } else {
levelEventPacket.setEventId(2038/*LevelEventType.SCULK_CHARGE_POP*/); levelEventPacket.setEventId(2038/*LevelEvent.SCULK_CHARGE_POP*/);
levelEventPacket.setTag( levelEventPacket.setTag(
NbtMap.builder() NbtMap.builder()
.putInt("x", packet.getPosition().getX()) .putInt("x", packet.getPosition().getX())
@ -288,7 +288,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
} }
case SCULK_SHRIEKER_SHRIEK -> { case SCULK_SHRIEKER_SHRIEK -> {
LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket(); LevelEventGenericPacket levelEventPacket = new LevelEventGenericPacket();
levelEventPacket.setEventId(2035/*LevelEventType.PARTICLE_SCULK_SHRIEK*/); levelEventPacket.setEventId(2035/*LevelEvent.PARTICLE_SCULK_SHRIEK*/);
levelEventPacket.setTag( levelEventPacket.setTag(
NbtMap.builder() NbtMap.builder()
.putInt("originX", packet.getPosition().getX()) .putInt("originX", packet.getPosition().getX())

Datei anzeigen

@ -26,15 +26,21 @@
package org.geysermc.geyser.translator.protocol.java.level; package org.geysermc.geyser.translator.protocol.java.level;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.game.level.particle.*; import com.github.steveice10.mc.protocol.data.game.level.particle.BlockParticleData;
import com.github.steveice10.mc.protocol.data.game.level.particle.DustParticleData;
import com.github.steveice10.mc.protocol.data.game.level.particle.FallingDustParticleData;
import com.github.steveice10.mc.protocol.data.game.level.particle.ItemParticleData;
import com.github.steveice10.mc.protocol.data.game.level.particle.Particle;
import com.github.steveice10.mc.protocol.data.game.level.particle.VibrationParticleData;
import com.github.steveice10.mc.protocol.data.game.level.particle.positionsource.BlockPositionSource; import com.github.steveice10.mc.protocol.data.game.level.particle.positionsource.BlockPositionSource;
import com.github.steveice10.mc.protocol.data.game.level.particle.positionsource.EntityPositionSource; import com.github.steveice10.mc.protocol.data.game.level.particle.positionsource.EntityPositionSource;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelParticlesPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelParticlesPacket;
import org.cloudburstmc.math.vector.Vector3f;
import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMap;
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket; import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket;
@ -92,7 +98,7 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
int blockState = session.getBlockMappings().getBedrockBlockId(((BlockParticleData) particle.getData()).getBlockState()); int blockState = session.getBlockMappings().getBedrockBlockId(((BlockParticleData) particle.getData()).getBlockState());
return (position) -> { return (position) -> {
LevelEventPacket packet = new LevelEventPacket(); LevelEventPacket packet = new LevelEventPacket();
packet.setType(LevelEventType.PARTICLE_CRACK_BLOCK); packet.setType(LevelEvent.PARTICLE_CRACK_BLOCK);
packet.setPosition(position); packet.setPosition(position);
packet.setData(blockState); packet.setData(blockState);
return packet; return packet;
@ -104,7 +110,7 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
LevelEventPacket packet = new LevelEventPacket(); LevelEventPacket packet = new LevelEventPacket();
// In fact, FallingDustParticle should have data like DustParticle, // In fact, FallingDustParticle should have data like DustParticle,
// but in MCProtocol, its data is BlockState(1). // but in MCProtocol, its data is BlockState(1).
packet.setType(LevelEventType.PARTICLE_FALLING_DUST); packet.setType(ParticleType.FALLING_DUST);
packet.setData(blockState); packet.setData(blockState);
packet.setPosition(position); packet.setPosition(position);
return packet; return packet;
@ -113,10 +119,10 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
case ITEM -> { case ITEM -> {
ItemStack javaItem = ((ItemParticleData) particle.getData()).getItemStack(); ItemStack javaItem = ((ItemParticleData) particle.getData()).getItemStack();
ItemData bedrockItem = ItemTranslator.translateToBedrock(session, javaItem); ItemData bedrockItem = ItemTranslator.translateToBedrock(session, javaItem);
int data = bedrockItem.getId() << 16 | bedrockItem.getDamage(); int data = bedrockItem.getDefinition().getRuntimeId() << 16 | bedrockItem.getDamage();
return (position) -> { return (position) -> {
LevelEventPacket packet = new LevelEventPacket(); LevelEventPacket packet = new LevelEventPacket();
packet.setType(LevelEventType.PARTICLE_ITEM_BREAK); packet.setType(ParticleType.ICON_CRACK);
packet.setData(data); packet.setData(data);
packet.setPosition(position); packet.setPosition(position);
return packet; return packet;
@ -130,7 +136,7 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
int rgbData = ((0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); int rgbData = ((0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
return (position) -> { return (position) -> {
LevelEventPacket packet = new LevelEventPacket(); LevelEventPacket packet = new LevelEventPacket();
packet.setType(LevelEventType.PARTICLE_FALLING_DUST); packet.setType(ParticleType.FALLING_DUST);
packet.setData(rgbData); packet.setData(rgbData);
packet.setPosition(position); packet.setPosition(position);
return packet; return packet;
@ -157,7 +163,7 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
return (position) -> { return (position) -> {
LevelEventGenericPacket packet = new LevelEventGenericPacket(); LevelEventGenericPacket packet = new LevelEventGenericPacket();
packet.setEventId(2027/*LevelEventType.PARTICLE_VIBRATION_SIGNAL*/); packet.setEventId(2027/*LevelEvent.PARTICLE_VIBRATION_SIGNAL*/);
packet.setTag( packet.setTag(
NbtMap.builder() NbtMap.builder()
.putCompound("origin", buildVec3PositionTag(position)) .putCompound("origin", buildVec3PositionTag(position))

Datei anzeigen

@ -117,10 +117,10 @@ public class JavaSetScoreTranslator extends PacketTranslator<ClientboundSetScore
String displayString = count + " " + objective.getDisplayName(); String displayString = count + " " + objective.getDisplayName();
// Of note: unlike Bedrock, if there is an objective in the below name slot, everyone has a display // Of note: unlike Bedrock, if there is an objective in the below name slot, everyone has a display
entity.getDirtyMetadata().put(EntityDataTypes.SCORE_TAG, displayString); entity.getDirtyMetadata().put(EntityDataTypes.SCORE, displayString);
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
entityDataPacket.getMetadata().put(EntityDataTypes.SCORE_TAG, displayString); entityDataPacket.getMetadata().put(EntityDataTypes.SCORE, displayString);
session.sendUpstreamPacket(entityDataPacket); session.sendUpstreamPacket(entityDataPacket);
} }

Datei anzeigen

@ -26,6 +26,7 @@
package org.geysermc.geyser.translator.sound.block; package org.geysermc.geyser.translator.sound.block;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -40,7 +41,7 @@ public class ComparatorSoundInteractionTranslator implements BlockSoundInteracti
boolean powered = identifier.contains("mode=compare"); boolean powered = identifier.contains("mode=compare");
LevelEventPacket levelEventPacket = new LevelEventPacket(); LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(position); levelEventPacket.setPosition(position);
levelEventPacket.setType(LevelEventType.SOUND_CLICK); //TODO: New ID? levelEventPacket.setType(LevelEvent.SOUND_CLICK); //TODO: New ID?
levelEventPacket.setData(powered ? 500 : 550); levelEventPacket.setData(powered ? 500 : 550);
session.sendUpstreamPacket(levelEventPacket); session.sendUpstreamPacket(levelEventPacket);
} }

Datei anzeigen

@ -26,6 +26,7 @@
package org.geysermc.geyser.translator.sound.block; package org.geysermc.geyser.translator.sound.block;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -39,7 +40,7 @@ public class DoorSoundInteractionTranslator implements BlockSoundInteractionTran
public void translate(GeyserSession session, Vector3f position, String identifier) { public void translate(GeyserSession session, Vector3f position, String identifier) {
if (identifier.contains("iron")) return; if (identifier.contains("iron")) return;
LevelEventPacket levelEventPacket = new LevelEventPacket(); LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setType(LevelEventType.SOUND_DOOR_OPEN); levelEventPacket.setType(LevelEvent.SOUND_DOOR_OPEN);
levelEventPacket.setPosition(position); levelEventPacket.setPosition(position);
levelEventPacket.setData(0); levelEventPacket.setData(0);
session.sendUpstreamPacket(levelEventPacket); session.sendUpstreamPacket(levelEventPacket);

Datei anzeigen

@ -26,6 +26,7 @@
package org.geysermc.geyser.translator.sound.block; package org.geysermc.geyser.translator.sound.block;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -40,7 +41,7 @@ public class LeverSoundInteractionTranslator implements BlockSoundInteractionTra
boolean powered = identifier.contains("powered=true"); boolean powered = identifier.contains("powered=true");
LevelEventPacket levelEventPacket = new LevelEventPacket(); LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(position); levelEventPacket.setPosition(position);
levelEventPacket.setType(LevelEventType.SOUND_CLICK); levelEventPacket.setType(LevelEvent.SOUND_CLICK);
levelEventPacket.setData(powered ? 600 : 500); levelEventPacket.setData(powered ? 600 : 500);
session.sendUpstreamPacket(levelEventPacket); session.sendUpstreamPacket(levelEventPacket);
} }

Datei anzeigen

@ -147,9 +147,9 @@ public class ChunkUtils {
waterPacket.setDataLayer(1); waterPacket.setDataLayer(1);
waterPacket.setBlockPosition(position); waterPacket.setBlockPosition(position);
if (BlockRegistries.WATERLOGGED.get().contains(blockState)) { if (BlockRegistries.WATERLOGGED.get().contains(blockState)) {
waterPacket.setRuntimeId(session.getBlockMappings().getBedrockWater()); waterPacket.setRuntimeId(session.getBlockMappings().getBedrockWater().getRuntimeId());
} else { } else {
waterPacket.setRuntimeId(session.getBlockMappings().getBedrockAir()); waterPacket.setRuntimeId(session.getBlockMappings().getBedrockAir().getRuntimeId());
} }
session.sendUpstreamPacket(waterPacket); session.sendUpstreamPacket(waterPacket);
} }
@ -171,8 +171,6 @@ public class ChunkUtils {
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension(); BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension();
int bedrockSubChunkCount = bedrockDimension.height() >> 4; int bedrockSubChunkCount = bedrockDimension.height() >> 4;
byte[] payload;
// Allocate output buffer // Allocate output buffer
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(ChunkUtils.EMPTY_BIOME_DATA.length * bedrockSubChunkCount + 1); // Consists only of biome data and border blocks ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(ChunkUtils.EMPTY_BIOME_DATA.length * bedrockSubChunkCount + 1); // Consists only of biome data and border blocks
try { try {
@ -182,9 +180,6 @@ public class ChunkUtils {
} }
byteBuf.writeByte(0); // Border blocks - Edu edition only byteBuf.writeByte(0); // Border blocks - Edu edition only
payload = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(payload);
} finally { } finally {
byteBuf.release(); byteBuf.release();
} }
@ -193,7 +188,7 @@ public class ChunkUtils {
data.setChunkX(chunkX); data.setChunkX(chunkX);
data.setChunkZ(chunkZ); data.setChunkZ(chunkZ);
data.setSubChunksLength(0); data.setSubChunksLength(0);
data.setData(payload); data.setData(byteBuf);
data.setCachingEnabled(false); data.setCachingEnabled(false);
session.sendUpstreamPacket(data); session.sendUpstreamPacket(data);

Datei anzeigen

@ -201,15 +201,15 @@ public final class EntityUtils {
public static void updateRiderRotationLock(Entity passenger, Entity mount, boolean isRiding) { public static void updateRiderRotationLock(Entity passenger, Entity mount, boolean isRiding) {
if (isRiding && mount instanceof BoatEntity) { if (isRiding && mount instanceof BoatEntity) {
// Head rotation is locked while riding in a boat // Head rotation is locked while riding in a boat
passenger.getDirtyMetadata().put(EntityDataTypes.RIDER_ROTATION_LOCKED, (byte) 1); passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION, true);
passenger.getDirtyMetadata().put(EntityDataTypes.RIDER_MAX_ROTATION, 90f); passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION_DEGREES, 90f);
passenger.getDirtyMetadata().put(EntityDataTypes.RIDER_MIN_ROTATION, 1f); passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_ROTATION_OFFSET, 1f);
passenger.getDirtyMetadata().put(EntityDataTypes.RIDER_ROTATION_OFFSET, -90f); passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_ROTATION_OFFSET_DEGREES, -90f);
} else { } else {
passenger.getDirtyMetadata().put(EntityDataTypes.RIDER_ROTATION_LOCKED, (byte) 0); passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION, false);
passenger.getDirtyMetadata().put(EntityDataTypes.RIDER_MAX_ROTATION, 0f); passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION_DEGREES, 0f);
passenger.getDirtyMetadata().put(EntityDataTypes.RIDER_MIN_ROTATION, 0f); passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_ROTATION_OFFSET, 0f);
passenger.getDirtyMetadata().put(EntityDataTypes.RIDER_ROTATION_OFFSET, 0f); passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_ROTATION_OFFSET_DEGREES, 0f);
} }
} }
@ -217,14 +217,14 @@ public final class EntityUtils {
* Determine if an action would result in a successful bucketing of the given entity. * Determine if an action would result in a successful bucketing of the given entity.
*/ */
public static boolean attemptToBucket(GeyserSession session, GeyserItemStack itemInHand) { public static boolean attemptToBucket(GeyserSession session, GeyserItemStack itemInHand) {
return itemInHand.getJavaId() == session.getItemMappings().getStoredItems().waterBucket(); return itemInHand.getJavaId() == session.getItemMappings().getStoredItems().waterBucket().getJavaId();
} }
/** /**
* Attempt to determine the result of saddling the given entity. * Attempt to determine the result of saddling the given entity.
*/ */
public static InteractionResult attemptToSaddle(GeyserSession session, Entity entityToSaddle, GeyserItemStack itemInHand) { public static InteractionResult attemptToSaddle(GeyserSession session, Entity entityToSaddle, GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().saddle()) { if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().saddle().getJavaId()) {
if (!entityToSaddle.getFlag(EntityFlag.SADDLED) && !entityToSaddle.getFlag(EntityFlag.BABY)) { if (!entityToSaddle.getFlag(EntityFlag.SADDLED) && !entityToSaddle.getFlag(EntityFlag.BABY)) {
// Saddle // Saddle
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;

Datei anzeigen

@ -186,7 +186,7 @@ public class InventoryUtils {
root.put("display", display.build()); root.put("display", display.build());
return protocolVersion -> ItemData.builder() return protocolVersion -> ItemData.builder()
.id(Registries.ITEMS.forVersion(protocolVersion).getStoredItems().barrier().getBedrockDefinition()) .definition(Registries.ITEMS.forVersion(protocolVersion).getStoredItems().barrier().getBedrockDefinition())
.count(1) .count(1)
.tag(root.build()).build(); .tag(root.build()).build();
} }

Datei anzeigen

@ -31,8 +31,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeType; import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.github.steveice10.mc.auth.service.MsaAuthenticationService; import com.github.steveice10.mc.auth.service.MsaAuthenticationService;
import com.nimbusds.jose.JWSObject; import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.shaded.json.JSONObject; import com.nimbusds.jose.shaded.json.JSONObject;
import com.nimbusds.jose.shaded.json.JSONValue; import com.nimbusds.jose.shaded.json.JSONValue;
import com.nimbusds.jwt.SignedJWT;
import com.nukkitx.network.util.Preconditions; import com.nukkitx.network.util.Preconditions;
import org.cloudburstmc.protocol.bedrock.packet.LoginPacket; import org.cloudburstmc.protocol.bedrock.packet.LoginPacket;
import org.cloudburstmc.protocol.bedrock.packet.ServerToClientHandshakePacket; import org.cloudburstmc.protocol.bedrock.packet.ServerToClientHandshakePacket;
@ -60,6 +62,7 @@ import java.security.PublicKey;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec; import java.security.spec.ECGenParameterSpec;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -68,17 +71,18 @@ public class LoginEncryptionUtils {
private static boolean HAS_SENT_ENCRYPTION_MESSAGE = false; private static boolean HAS_SENT_ENCRYPTION_MESSAGE = false;
private static boolean validateChainData(JsonNode data) throws Exception { private static boolean validateChainData(List<SignedJWT> chain) throws Exception {
if (data.size() != 3) { if (chain.size() != 3) {
return false; return false;
} }
Payload identity = null;
ECPublicKey lastKey = null; ECPublicKey lastKey = null;
boolean mojangSigned = false; boolean mojangSigned = false;
Iterator<JsonNode> iterator = data.iterator(); Iterator<SignedJWT> iterator = chain.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
JsonNode node = iterator.next(); SignedJWT jwt = iterator.next();
JWSObject jwt = JWSObject.parse(node.asText()); identity = jwt.getPayload();
// x509 cert is expected in every claim // x509 cert is expected in every claim
URI x5u = jwt.getHeader().getX509CertURL(); URI x5u = jwt.getHeader().getX509CertURL();
@ -118,22 +122,10 @@ public class LoginEncryptionUtils {
} }
public static void encryptPlayerConnection(GeyserSession session, LoginPacket loginPacket) { public static void encryptPlayerConnection(GeyserSession session, LoginPacket loginPacket) {
JsonNode certData; encryptConnectionWithCert(session, loginPacket.getExtra().toString(), loginPacket.getChain());
try {
certData = JSON_MAPPER.readTree(loginPacket.getChainData().toByteArray());
} catch (IOException ex) {
throw new RuntimeException("Certificate JSON can not be read.");
}
JsonNode certChainData = certData.get("chain");
if (certChainData.getNodeType() != JsonNodeType.ARRAY) {
throw new RuntimeException("Certificate data is not valid");
}
encryptConnectionWithCert(session, loginPacket.getSkinData().toString(), certChainData);
} }
private static void encryptConnectionWithCert(GeyserSession session, String clientData, JsonNode certChainData) { private static void encryptConnectionWithCert(GeyserSession session, String clientData, List<SignedJWT> certChainData) {
try { try {
GeyserImpl geyser = session.getGeyser(); GeyserImpl geyser = session.getGeyser();
@ -145,7 +137,7 @@ public class LoginEncryptionUtils {
session.disconnect(GeyserLocale.getLocaleStringLog("geyser.network.remote.invalid_xbox_account")); session.disconnect(GeyserLocale.getLocaleStringLog("geyser.network.remote.invalid_xbox_account"));
return; return;
} }
JWSObject jwt = JWSObject.parse(certChainData.get(certChainData.size() - 1).asText()); JWSObject jwt = certChainData.get(certChainData.size() - 1);
JsonNode payload = JSON_MAPPER.readTree(jwt.getPayload().toBytes()); JsonNode payload = JSON_MAPPER.readTree(jwt.getPayload().toBytes());
if (payload.get("extraData").getNodeType() != JsonNodeType.OBJECT) { if (payload.get("extraData").getNodeType() != JsonNodeType.OBJECT) {

Datei anzeigen

@ -29,7 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.level.sound.BuiltinSound;
import com.github.steveice10.mc.protocol.data.game.level.sound.CustomSound; import com.github.steveice10.mc.protocol.data.game.level.sound.CustomSound;
import com.github.steveice10.mc.protocol.data.game.level.sound.Sound; import com.github.steveice10.mc.protocol.data.game.level.sound.Sound;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType; import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
@ -123,7 +123,7 @@ public final class SoundUtils {
LevelEventPacket levelEventPacket = new LevelEventPacket(); LevelEventPacket levelEventPacket = new LevelEventPacket();
levelEventPacket.setPosition(position); levelEventPacket.setPosition(position);
levelEventPacket.setData(0); levelEventPacket.setData(0);
levelEventPacket.setType(LevelEventType.valueOf(soundMapping.getBedrock())); levelEventPacket.setType(LevelEvent.valueOf(soundMapping.getBedrock()));
session.sendUpstreamPacket(levelEventPacket); session.sendUpstreamPacket(levelEventPacket);
return; return;
} }