From bbf45b6a4cc8ec3b389923d5b6dbca3e83ce21b0 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 25 May 2022 15:55:15 -0400 Subject: [PATCH] Compiles; provide your own mappings for now --- core/pom.xml | 4 +- .../command/defaults/OffhandCommand.java | 2 +- .../geyser/entity/EntityDefinitions.java | 2 +- .../geyser/entity/type/PaintingEntity.java | 19 +++--- .../type/living/animal/HoglinEntity.java | 2 +- .../type/living/monster/BasePiglinEntity.java | 2 +- .../geyser/level/GeyserWorldManager.java | 9 ++- .../geysermc/geyser/level/JavaDimension.java | 24 ++++++-- .../geyser/network/MinecraftProtocol.java | 6 -- .../populator/BlockRegistryPopulator.java | 6 +- .../populator/ItemRegistryPopulator.java | 4 +- .../geyser/session/GeyserSession.java | 37 +++++++++-- .../geyser/session/cache/TagCache.java | 1 + .../inventory/BeaconInventoryTranslator.java | 8 ++- .../translator/level/BiomeTranslator.java | 36 +++++------ .../BedrockCommandRequestTranslator.java | 7 +-- ...BedrockInventoryTransactionTranslator.java | 18 +++--- .../BedrockLecternUpdateTranslator.java | 3 +- .../BedrockMobEquipmentTranslator.java | 2 +- .../bedrock/BedrockTextTranslator.java | 4 +- .../player/BedrockActionTranslator.java | 10 +-- .../entity/player/BedrockEmoteTranslator.java | 2 +- .../protocol/java/JavaCommandsTranslator.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 57 ++++++++++++++--- .../java/JavaPlayerChatTranslator.java | 60 ++++++++++++++++++ .../protocol/java/JavaRespawnTranslator.java | 9 +-- .../java/JavaSystemChatTranslator.java | 1 + .../org/geysermc/geyser/util/ChunkUtils.java | 22 +++---- .../geysermc/geyser/util/DimensionUtils.java | 22 ------- .../geysermc/geyser/util/JavaCodecEntry.java | 61 +++++++++++++++++++ 30 files changed, 310 insertions(+), 132 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java create mode 100644 core/src/main/java/org/geysermc/geyser/util/JavaCodecEntry.java diff --git a/core/pom.xml b/core/pom.xml index c9047ee4b..2d06c6bff 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -120,8 +120,8 @@ com.github.CloudburstMC.Protocol - bedrock-v503 - 297567d + bedrock-beta + 49323e0 compile diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java index 1d29d5122..f17ca5e21 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java @@ -47,7 +47,7 @@ public class OffhandCommand extends GeyserCommand { } ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.SWAP_HANDS, BlockUtils.POSITION_ZERO, - Direction.DOWN); + Direction.DOWN, session.getNextSequence()); session.sendDownstreamPacket(releaseItemPacket); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 1de571c94..7069b55b2 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -272,7 +272,7 @@ public final class EntityDefinitions { .type(EntityType.LLAMA_SPIT) .heightAndWidth(0.25f) .build(); - PAINTING = EntityDefinition.inherited(null, entityBase) + PAINTING = EntityDefinition.inherited(PaintingEntity::new, entityBase) .type(EntityType.PAINTING) .build(); SHULKER_BULLET = EntityDefinition.inherited(ThrowableEntity::new, entityBase) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java index 9a2bbd5a4..3fa4e90b2 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/PaintingEntity.java @@ -27,26 +27,27 @@ package org.geysermc.geyser.entity.type; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.packet.AddPaintingPacket; -import org.geysermc.geyser.entity.EntityDefinitions; -import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.level.PaintingType; +import org.geysermc.geyser.session.GeyserSession; import java.util.UUID; -// TODO 1.19 public class PaintingEntity extends Entity { private static final double OFFSET = -0.46875; - private final PaintingType paintingName; - private final int direction; + private PaintingType paintingName; + private int direction; - public PaintingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position, PaintingType paintingName, int direction) { - super(session, entityId, geyserId, uuid, EntityDefinitions.PAINTING, position, Vector3f.ZERO, 0f, 0f, 0f); - this.paintingName = paintingName; - this.direction = direction; + public PaintingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) { + super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw); } @Override public void spawnEntity() { + // Wait until we get the metadata needed + } + + public void paintingtodo() { AddPaintingPacket addPaintingPacket = new AddPaintingPacket(); addPaintingPacket.setUniqueEntityId(geyserId); addPaintingPacket.setRuntimeEntityId(geyserId); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java index 362c25256..a96d3072c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/HoglinEntity.java @@ -49,7 +49,7 @@ public class HoglinEntity extends AnimalEntity { @Override protected boolean isShaking() { - return (!isImmuneToZombification && !session.isDimensionPiglinSafe()) || super.isShaking(); + return (!isImmuneToZombification && !session.getDimensionType().piglinSafe()) || super.isShaking(); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java index ed26a71e1..e003dd080 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/BasePiglinEntity.java @@ -48,6 +48,6 @@ public class BasePiglinEntity extends MonsterEntity { @Override protected boolean isShaking() { - return (!isImmuneToZombification && !session.isDimensionPiglinSafe()) || super.isShaking(); + return (!isImmuneToZombification && !session.getDimensionType().piglinSafe()) || super.isShaking(); } } diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java index 5766cabbf..100917793 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserWorldManager.java @@ -27,15 +27,14 @@ package org.geysermc.geyser.level; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMapBuilder; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.ChunkCache; import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator; -import org.geysermc.geyser.level.block.BlockStateValues; import java.util.Locale; @@ -83,7 +82,7 @@ public class GeyserWorldManager extends WorldManager { @Override public void setGameRule(GeyserSession session, String name, Object value) { - session.sendDownstreamPacket(new ServerboundChatPacket("/gamerule " + name + " " + value)); + session.sendCommand("gamerule " + name + " " + value); gameruleCache.put(name, String.valueOf(value)); } @@ -109,12 +108,12 @@ public class GeyserWorldManager extends WorldManager { @Override public void setPlayerGameMode(GeyserSession session, GameMode gameMode) { - session.sendDownstreamPacket(new ServerboundChatPacket("/gamemode " + gameMode.name().toLowerCase(Locale.ROOT))); + session.sendCommand("gamemode " + gameMode.name().toLowerCase(Locale.ROOT)); } @Override public void setDifficulty(GeyserSession session, Difficulty difficulty) { - session.sendDownstreamPacket(new ServerboundChatPacket("/difficulty " + difficulty.name().toLowerCase(Locale.ROOT))); + session.sendCommand("difficulty " + difficulty.name().toLowerCase(Locale.ROOT)); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index b297739a9..45ccf3821 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -26,17 +26,31 @@ package org.geysermc.geyser.level; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntTag; +import org.geysermc.geyser.util.JavaCodecEntry; + +import java.util.Map; /** * Represents the information we store from the current Java dimension * @param piglinSafe Whether piglins and hoglins are safe from conversion in this dimension. * This controls if they have the shaking effect applied in the dimension. */ -public record JavaDimension(int minY, int maxY, boolean piglinSafe) { +public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) { - public static JavaDimension load(CompoundTag tag) { -// int minY = ((IntTag) dimensionTag.get("min_y")).getValue(); -// int maxY = ((IntTag) dimensionTag.get("height")).getValue(); - return new JavaDimension(0, 0, false); + public static void load(CompoundTag tag, Map map) { + for (CompoundTag dimension : JavaCodecEntry.iterateOverTag(tag.get("minecraft:dimension_type"))) { + CompoundTag elements = dimension.get("element"); + int minY = ((IntTag) elements.get("min_y")).getValue(); + int maxY = ((IntTag) elements.get("height")).getValue(); + // Logical height can be ignored probably - seems to be for artificial limits like the Nether. + + // Set if piglins/hoglins should shake + boolean piglinSafe = ((Number) elements.get("piglin_safe").getValue()).byteValue() != (byte) 0; + // Load world coordinate scale for the world border + double coordinateScale = ((Number) elements.get("coordinate_scale").getValue()).doubleValue(); + + map.put((String) dimension.get("name").getValue(), new JavaDimension(minY, maxY, piglinSafe, coordinateScale)); + } } } diff --git a/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java b/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java index 828b04a9d..f4afceb21 100644 --- a/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java +++ b/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java @@ -28,8 +28,6 @@ package org.geysermc.geyser.network; import com.github.steveice10.mc.protocol.codec.MinecraftCodec; import com.github.steveice10.mc.protocol.codec.PacketCodec; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; -import com.nukkitx.protocol.bedrock.v475.Bedrock_v475; -import com.nukkitx.protocol.bedrock.v486.Bedrock_v486; import com.nukkitx.protocol.bedrock.v503.Bedrock_v503; import java.util.ArrayList; @@ -58,10 +56,6 @@ public final class MinecraftProtocol { private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC; static { - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v475.V475_CODEC.toBuilder().minecraftVersion("1.18.0/1.18.1/1.18.2").build()); - SUPPORTED_BEDROCK_CODECS.add(Bedrock_v486.V486_CODEC.toBuilder() - .minecraftVersion("1.18.10/1.18.12") // 1.18.11 is also supported, but was only on Switch and since that auto-updates it's not needed - .build()); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder() .minecraftVersion("1.18.30/1.18.31") .build()); diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java index 412d7d779..55782447f 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java @@ -171,8 +171,10 @@ public class BlockRegistryPopulator { int bedrockRuntimeId = blockStateOrderedMap.getOrDefault(buildBedrockState(entry.getValue(), stateVersion, stateMapper), -1); if (bedrockRuntimeId == -1) { - throw new RuntimeException("Unable to find " + javaId + " Bedrock runtime ID! Built NBT tag: \n" + - buildBedrockState(entry.getValue(), stateVersion, stateMapper)); + bedrockRuntimeId = 0; + //TODO remove + //throw new RuntimeException("Unable to find " + javaId + " Bedrock runtime ID! Built NBT tag: \n" + + // buildBedrockState(entry.getValue(), stateVersion, stateMapper)); } switch (javaId) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index 37b6c49f4..39321ae02 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -252,7 +252,9 @@ public class ItemRegistryPopulator { int bedrockId = bedrockIdentifierToId.getInt(bedrockIdentifier); if (bedrockId == Short.MIN_VALUE) { - throw new RuntimeException("Missing Bedrock ID in mappings: " + bedrockIdentifier); + bedrockId = 0; + //TODO remove + //throw new RuntimeException("Missing Bedrock ID in mappings: " + bedrockIdentifier); } int stackSize = mappingItem.getStackSize(); diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 607c9f84d..e93c7392e 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -36,6 +36,7 @@ import com.github.steveice10.mc.protocol.MinecraftConstants; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.ProtocolState; import com.github.steveice10.mc.protocol.data.UnexpectedEncryptionException; +import com.github.steveice10.mc.protocol.data.game.MessageType; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.object.Direction; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; @@ -47,6 +48,8 @@ import com.github.steveice10.mc.protocol.data.game.setting.SkinPart; import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic; import com.github.steveice10.mc.protocol.data.game.statistic.Statistic; import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientInformationPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; @@ -69,6 +72,7 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.packet.*; import io.netty.channel.Channel; import io.netty.channel.EventLoop; +import it.unimi.dsi.fastutil.bytes.ByteArrays; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -81,6 +85,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NonNull; import lombok.Setter; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.common.value.qual.IntRange; import org.geysermc.common.PlatformType; import org.geysermc.cumulus.Form; @@ -125,6 +130,7 @@ import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; +import java.time.Instant; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledFuture; @@ -319,11 +325,16 @@ public class GeyserSession implements GeyserConnection, CommandSender { */ @Setter private String dimension = DimensionUtils.OVERWORLD; + @MonotonicNonNull + @Setter + private JavaDimension dimensionType = null; /** * All dimensions that the client could possibly connect to. */ private final Map dimensions = new Object2ObjectOpenHashMap<>(3); + private final Map chatTypes = new EnumMap<>(MessageType.class); + @Setter private int breakingBlock; @@ -1260,9 +1271,9 @@ public class GeyserSession implements GeyserConnection, CommandSender { ServerboundUseItemPacket useItemPacket; if (playerInventory.getItemInHand().getJavaId() == shield.getJavaId()) { - useItemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, 0); //TODO + useItemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, getNextSequence()); } else if (playerInventory.getOffhand().getJavaId() == shield.getJavaId()) { - useItemPacket = new ServerboundUseItemPacket(Hand.OFF_HAND, 0); + useItemPacket = new ServerboundUseItemPacket(Hand.OFF_HAND, getNextSequence()); } else { // No blocking return false; @@ -1291,7 +1302,7 @@ public class GeyserSession implements GeyserConnection, CommandSender { private boolean disableBlocking() { if (playerEntity.getFlag(EntityFlag.BLOCKING)) { ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, - BlockUtils.POSITION_ZERO, Direction.DOWN, 0); //TODO + BlockUtils.POSITION_ZERO, Direction.DOWN, getNextSequence()); sendDownstreamPacket(releaseItemPacket); playerEntity.setFlag(EntityFlag.BLOCKING, false); return true; @@ -1357,7 +1368,21 @@ public class GeyserSession implements GeyserConnection, CommandSender { @Override public String getLocale() { return clientData.getLanguageCode(); - } + } + + /** + * Sends a chat message to the Java server. + */ + public void sendChat(String message) { + sendDownstreamPacket(new ServerboundChatPacket(message, Instant.now().toEpochMilli(), 0L, ByteArrays.EMPTY_ARRAY, false)); + } + + /** + * Sends a command to the Java server. + */ + public void sendCommand(String command) { + sendDownstreamPacket(new ServerboundChatCommandPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyMap(), false)); + } public void setServerRenderDistance(int renderDistance) { renderDistance = GenericMath.ceil(++renderDistance * MathUtils.SQRT_OF_TWO); //square to circle @@ -1636,6 +1661,10 @@ public class GeyserSession implements GeyserConnection, CommandSender { sendDownstreamPacket(clientSettingsPacket); } + public int getNextSequence() { + return 0; + } + /** * Used for updating statistic values since we only get changes from the server * diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java index d46a39616..993d93e0b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java @@ -69,6 +69,7 @@ public class TagCache { } public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) { + System.out.println(packet); Map blockTags = packet.getTags().get("minecraft:block"); this.leaves = IntList.of(blockTags.get("minecraft:leaves")); this.wool = IntList.of(blockTags.get("minecraft:wool")); diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java index f194d0d3f..54dc533c6 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java @@ -48,6 +48,8 @@ import org.geysermc.geyser.inventory.updater.UIInventoryUpdater; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InventoryUtils; +import java.util.OptionalInt; + public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator { public BeaconInventoryTranslator() { super(1, new BlockInventoryHolder("minecraft:beacon", com.nukkitx.protocol.bedrock.data.inventory.ContainerType.BEACON) { @@ -111,11 +113,15 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator public ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { // Input a beacon payment BeaconPaymentStackRequestActionData beaconPayment = (BeaconPaymentStackRequestActionData) request.getActions()[0]; - ServerboundSetBeaconPacket packet = new ServerboundSetBeaconPacket(beaconPayment.getPrimaryEffect(), beaconPayment.getSecondaryEffect()); + ServerboundSetBeaconPacket packet = new ServerboundSetBeaconPacket(toJava(beaconPayment.getPrimaryEffect()), toJava(beaconPayment.getSecondaryEffect())); session.sendDownstreamPacket(packet); return acceptRequest(request, makeContainerEntries(session, inventory, IntSets.emptySet())); } + private OptionalInt toJava(int effectChoice) { + return effectChoice == -1 ? OptionalInt.empty() : OptionalInt.of(effectChoice); + } + @Override public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) { if (slotInfoData.getContainer() == ContainerSlotType.BEACON_PAYMENT) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index ac9a0517a..24b6f950f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -42,6 +42,7 @@ import org.geysermc.geyser.level.chunk.bitarray.BitArray; import org.geysermc.geyser.level.chunk.bitarray.BitArrayVersion; import org.geysermc.geyser.level.chunk.bitarray.SingletonBitArray; import org.geysermc.geyser.registry.Registries; +import org.geysermc.geyser.util.JavaCodecEntry; import org.geysermc.geyser.util.MathUtils; // Array index formula by https://wiki.vg/Chunk_Format @@ -55,27 +56,26 @@ public class BiomeTranslator { ListTag serverBiomes = worldGen.get("value"); session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(serverBiomes.size())); - for (Tag tag : serverBiomes) { - CompoundTag biomeTag = (CompoundTag) tag; - + for (CompoundTag biomeTag : JavaCodecEntry.iterateOverTag(worldGen)) { String javaIdentifier = ((StringTag) biomeTag.get("name")).getValue(); - int bedrockId = Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, -1); + int bedrockId = Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); int javaId = ((IntTag) biomeTag.get("id")).getValue(); - if (bedrockId == -1) { - // There is no matching Bedrock variation for this biome; let's set the closest match based on biome category - String category = ((StringTag) ((CompoundTag) biomeTag.get("element")).get("category")).getValue(); - String replacementBiome = switch (category) { - case "extreme_hills" -> "minecraft:mountains"; - case "icy" -> "minecraft:ice_spikes"; - case "mesa" -> "minecraft:badlands"; - case "mushroom" -> "minecraft:mushroom_fields"; - case "nether" -> "minecraft:nether_wastes"; - default -> "minecraft:ocean"; // Typically ID 0 so a good default - case "taiga", "jungle", "plains", "savanna", "the_end", "beach", "ocean", "desert", "river", "swamp" -> "minecraft:" + category; - }; - bedrockId = Registries.BIOME_IDENTIFIERS.get().getInt(replacementBiome); - } + // TODO - the category tag no longer exists - find a better replacement option +// if (bedrockId == -1) { +// // There is no matching Bedrock variation for this biome; let's set the closest match based on biome category +// String category = ((StringTag) ((CompoundTag) biomeTag.get("element")).get("category")).getValue(); +// String replacementBiome = switch (category) { +// case "extreme_hills" -> "minecraft:mountains"; +// case "icy" -> "minecraft:ice_spikes"; +// case "mesa" -> "minecraft:badlands"; +// case "mushroom" -> "minecraft:mushroom_fields"; +// case "nether" -> "minecraft:nether_wastes"; +// default -> "minecraft:ocean"; // Typically ID 0 so a good default +// case "taiga", "jungle", "plains", "savanna", "the_end", "beach", "ocean", "desert", "river", "swamp" -> "minecraft:" + category; +// }; +// bedrockId = Registries.BIOME_IDENTIFIERS.get().getInt(replacementBiome); +// } // When we see the Java ID, we should instead apply the Bedrock ID biomeTranslations.put(javaId, bedrockId); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java index 73ca9b222..0aa57b077 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java @@ -25,15 +25,13 @@ package org.geysermc.geyser.translator.protocol.bedrock; +import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket; import org.geysermc.common.PlatformType; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.CommandManager; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; - -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; -import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket; import org.geysermc.geyser.translator.text.MessageTranslator; @Translator(packet = CommandRequestPacket.class) @@ -52,8 +50,7 @@ public class BedrockCommandRequestTranslator extends PacketTranslator { - ServerboundUseItemPacket itemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND); + ServerboundUseItemPacket itemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getNextSequence()); session.sendDownstreamPacket(itemPacket); }, 5, TimeUnit.MILLISECONDS)); } @@ -336,7 +338,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator legacySlots = packet.getLegacySlots(); @@ -418,7 +420,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator session.sendDownstreamPacket(new ServerboundUseItemPacket(Hand.MAIN_HAND)), + session.scheduleInEventLoop(() -> session.sendDownstreamPacket(new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getNextSequence())), 50, TimeUnit.MILLISECONDS); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockTextTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockTextTranslator.java index 91ed5aa2b..e52fac371 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockTextTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockTextTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; import com.nukkitx.protocol.bedrock.packet.TextPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; @@ -63,7 +62,6 @@ public class BedrockTextTranslator extends PacketTranslator { return; } - ServerboundChatPacket chatPacket = new ServerboundChatPacket(message); - session.sendDownstreamPacket(chatPacket); + session.sendChat(message); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java index 5429899fa..f6edd731b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockActionTranslator.java @@ -130,7 +130,8 @@ public class BedrockActionTranslator extends PacketTranslator { if (session.getGeyser().getConfig().getEmoteOffhandWorkaround() != EmoteOffhandWorkaroundOption.DISABLED) { // Activate the workaround - we should trigger the offhand now ServerboundPlayerActionPacket swapHandsPacket = new ServerboundPlayerActionPacket(PlayerAction.SWAP_HANDS, BlockUtils.POSITION_ZERO, - Direction.DOWN); + Direction.DOWN, session.getNextSequence()); session.sendDownstreamPacket(swapHandsPacket); if (session.getGeyser().getConfig().getEmoteOffhandWorkaround() == EmoteOffhandWorkaroundOption.NO_EMOTES) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java index 00b60fec0..115a44bdd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java @@ -222,7 +222,7 @@ public class JavaCommandsTranslator extends PacketTranslator CommandParam.BLOCK_POSITION; case COLUMN_POS, VEC3 -> CommandParam.POSITION; case MESSAGE -> CommandParam.MESSAGE; - case NBT, NBT_COMPOUND_TAG, NBT_TAG, NBT_PATH -> CommandParam.JSON; + case NBT_COMPOUND_TAG, NBT_TAG, NBT_PATH -> CommandParam.JSON; //TODO NBT was removed case RESOURCE_LOCATION, FUNCTION -> CommandParam.FILE_PATH; case BOOL -> ENUM_BOOLEAN; case OPERATION -> CommandParam.OPERATOR; // ">=", "==", etc diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index c7165083d..b7f169627 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -25,8 +25,12 @@ package org.geysermc.geyser.translator.protocol.java; +import com.github.steveice10.mc.protocol.data.game.MessageType; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket; +import com.github.steveice10.opennbt.SNBTIO; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.nukkitx.protocol.bedrock.data.GameRuleData; import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; @@ -40,8 +44,14 @@ import org.geysermc.geyser.session.auth.AuthType; import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.geyser.util.ChunkUtils; +import org.geysermc.geyser.util.DimensionUtils; +import org.geysermc.geyser.util.JavaCodecEntry; import org.geysermc.geyser.util.PluginMessageUtils; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Map; @Translator(packet = ClientboundLoginPacket.class) @@ -55,12 +65,37 @@ public class JavaLoginTranslator extends PacketTranslator dimensions = session.getDimensions(); dimensions.clear(); + JavaDimension.load(packet.getDimensionCodec(), dimensions); + + SNBTIO.StringifiedNBTWriter writer = new SNBTIO.StringifiedNBTWriter(System.out); + try { + writer.writeTag(packet.getDimensionCodec(), true); + } catch (IOException e) { + e.printStackTrace(); + } + + for (CompoundTag tag : JavaCodecEntry.iterateOverTag(packet.getDimensionCodec().get("minecraft:chat_type"))) { + int id = ((IntTag) tag.get("id")).getValue(); + MessageType type = MessageType.values()[id]; + CompoundTag element = tag.get("element"); + CompoundTag chat = element.get("chat"); + if (chat == null) { + continue; + } + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); SNBTIO.StringifiedNBTWriter nbtWriter = new SNBTIO.StringifiedNBTWriter(out)) { + nbtWriter.writeTag(chat, false); + System.out.println(out.toString(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } + // If the player is already initialized and a join game packet is sent, they // are swapping servers - //String newDimension = DimensionUtils.getNewDimension(packet.getDimension()); if (session.isSpawned()) { - //String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension); - //DimensionUtils.switchDimension(session, fakeDim); + String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), packet.getDimension()); + DimensionUtils.switchDimension(session, fakeDim); session.getWorldCache().removeScoreboard(); } @@ -110,13 +145,15 @@ public class JavaLoginTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, ClientboundPlayerChatPacket packet) { + System.out.println(packet); + TextPacket textPacket = new TextPacket(); + textPacket.setPlatformChatId(""); + textPacket.setSourceName(""); + textPacket.setXuid(session.getAuthData().xuid()); + // TODO new types + textPacket.setType(switch (packet.getType()) { + case CHAT -> TextPacket.Type.CHAT; + case SYSTEM -> TextPacket.Type.SYSTEM; + case GAME_INFO -> TextPacket.Type.TIP; + default -> TextPacket.Type.RAW; + }); + + textPacket.setNeedsTranslation(false); + Component message = packet.getUnsignedContent() == null ? packet.getSignedContent() : packet.getUnsignedContent(); + textPacket.setMessage(MessageTranslator.convertMessage(message, session.getLocale())); + + session.sendUpstreamPacket(textPacket); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java index 03d006a50..2d8c379f9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java @@ -33,9 +33,9 @@ import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; -import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.DimensionUtils; @@ -78,7 +78,7 @@ public class JavaRespawnTranslator extends PacketTranslator iterateOverTag(CompoundTag tag) { + ListTag value = tag.get("value"); + Iterator originalIterator = value.iterator(); + return new Iterable<>() { + @Nonnull + @Override + public Iterator iterator() { + return new Iterator<>() { + @Override + public boolean hasNext() { + return originalIterator.hasNext(); + } + + @Override + public CompoundTag next() { + return (CompoundTag) originalIterator.next(); + } + }; + } + }; + } +}