From 9875d204e32f8c0d6544506b1177b5eb1b903a38 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Wed, 27 Nov 2019 19:30:30 -0600 Subject: [PATCH] Add more entity metadata translations and fix autojump (Closes #73) --- .../org/geysermc/connector/entity/Entity.java | 54 +++++++++----- .../geysermc/connector/entity/ItemEntity.java | 58 +++++++++++++++ .../connector/entity/PaintingEntity.java | 25 +++++++ .../network/translators/TranslatorsInit.java | 6 +- .../entity/JavaEntityMetadataTranslator.java | 35 +-------- .../player/JavaPlayerAbilitiesTranslator.java | 72 +++++++++++++++++++ 6 files changed, 193 insertions(+), 57 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index 8824c9534..ba9fe4ab3 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -25,16 +25,15 @@ package org.geysermc.connector.entity; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPropertiesPacket; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; +import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.EntityDataDictionary; import com.nukkitx.protocol.bedrock.data.EntityFlag; import com.nukkitx.protocol.bedrock.data.EntityFlags; -import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; -import com.nukkitx.protocol.bedrock.packet.RemoveEntityPacket; -import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; -import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; +import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; import lombok.Setter; import org.geysermc.connector.console.GeyserLogger; @@ -43,6 +42,7 @@ import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.AttributeUtils; +import org.geysermc.connector.utils.MessageUtils; import java.util.*; @@ -164,6 +164,36 @@ public class Entity { updateAttributesPacket.setRuntimeEntityId(geyserId); updateAttributesPacket.setAttributes(attributes); session.getUpstream().sendPacket(updateAttributesPacket); + } + + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + switch (entityMetadata.getId()) { + case 0: + if (entityMetadata.getType() == MetadataType.BYTE) { + byte xd = (byte) entityMetadata.getValue(); + metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01); + metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02); + metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08); + metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10); + metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); + metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20); + } + break; + case 2: // custom name + TextMessage name = (TextMessage) entityMetadata.getValue(); + if (name != null) + metadata.put(EntityData.NAMETAG, MessageUtils.getBedrockMessage(name)); + break; + case 3: // is custom name visible + metadata.getFlags().setFlag(EntityFlag.ALWAYS_SHOW_NAME, (boolean) entityMetadata.getValue()); + break; + case 4: // silent + metadata.getFlags().setFlag(EntityFlag.SILENT, (boolean) entityMetadata.getValue()); + break; + case 5: // no gravity + metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue()); + break; + } SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entityDataPacket.setRuntimeEntityId(geyserId); @@ -171,20 +201,6 @@ public class Entity { session.getUpstream().sendPacket(entityDataPacket); } - // To be used at a later date - public void updateJavaAttributes(GeyserSession session) { - List attributes = new ArrayList<>(); - for (Map.Entry entry : this.attributes.entrySet()) { - if (!entry.getValue().getType().isBedrockAttribute()) - continue; - - attributes.add(AttributeUtils.getJavaAttribute(entry.getValue())); - } - - ServerEntityPropertiesPacket entityPropertiesPacket = new ServerEntityPropertiesPacket((int) entityId, attributes); - session.getDownstream().getSession().send(entityPropertiesPacket); - } - public void setPosition(Vector3f position) { if (is(PlayerEntity.class)) { this.position = position.add(0, entityType.getOffset(), 0); diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java new file mode 100644 index 000000000..78c78f3fd --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.entity; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.packet.AddItemEntityPacket; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.TranslatorsInit; + +public class ItemEntity extends Entity { + + public ItemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 7) { + AddItemEntityPacket itemPacket = new AddItemEntityPacket(); + itemPacket.setRuntimeEntityId(geyserId); + itemPacket.setPosition(position); + itemPacket.setMotion(motion); + itemPacket.setUniqueEntityId(geyserId); + itemPacket.setFromFishing(false); + itemPacket.getMetadata().putAll(metadata); + itemPacket.setItemInHand(TranslatorsInit.getItemTranslator().translateToBedrock((ItemStack) entityMetadata.getValue())); + session.getUpstream().sendPacket(itemPacket); + } + + super.updateBedrockMetadata(entityMetadata, session); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java index f9f6e37fd..b598b9bf3 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + package org.geysermc.connector.entity; import com.nukkitx.math.vector.Vector3f; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 6539fb05d..694ae525a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -27,10 +27,7 @@ package org.geysermc.connector.network.translators; import com.github.steveice10.mc.protocol.packet.ingame.server.*; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.*; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerActionAckPacket; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerHealthPacket; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerSetExperiencePacket; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.*; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.*; import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerDisplayScoreboardPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerScoreboardObjectivePacket; @@ -129,6 +126,7 @@ public class TranslatorsInit { Registry.registerJava(ServerPlayerSetExperiencePacket.class, new JavaPlayerSetExperienceTranslator()); Registry.registerJava(ServerPlayerHealthPacket.class, new JavaPlayerHealthTranslator()); Registry.registerJava(ServerPlayerActionAckPacket.class, new JavaPlayerActionAckTranslator()); + Registry.registerJava(ServerPlayerAbilitiesPacket.class, new JavaPlayerAbilitiesTranslator()); Registry.registerJava(ServerNotifyClientPacket.class, new JavaNotifyClientTranslator()); Registry.registerJava(ServerChunkDataPacket.class, new JavaChunkDataTranslator()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityMetadataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityMetadataTranslator.java index a21b2f86e..85efcc686 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityMetadataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityMetadataTranslator.java @@ -26,17 +26,10 @@ package org.geysermc.connector.network.translators.java.entity; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityMetadataPacket; -import com.nukkitx.protocol.bedrock.data.EntityFlag; -import com.nukkitx.protocol.bedrock.packet.AddItemEntityPacket; -import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; -import org.geysermc.connector.network.translators.TranslatorsInit; public class JavaEntityMetadataTranslator extends PacketTranslator { @@ -49,35 +42,9 @@ public class JavaEntityMetadataTranslator extends PacketTranslator { + + @Override + public void translate(ServerPlayerAbilitiesPacket packet, GeyserSession session) { + Entity entity = session.getPlayerEntity(); + if (entity == null) + return; + + EntityDataDictionary metadata = entity.getMetadata(); + metadata.getFlags().setFlag(EntityFlag.CAN_FLY, packet.isCanFly()); + + SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); + entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); + entityDataPacket.getMetadata().putAll(metadata); + session.getUpstream().sendPacket(entityDataPacket); + + int playerFlags = 0; + + playerFlags = setPlayerFlag(0x20, true, playerFlags); // auto jump + playerFlags = setPlayerFlag(0x40, packet.isCanFly(), playerFlags); // can fly + playerFlags = setPlayerFlag(0x200, packet.isFlying(), playerFlags); // is flying + + AdventureSettingsPacket adventureSettingsPacket = new AdventureSettingsPacket(); + adventureSettingsPacket.setUniqueEntityId(entity.getGeyserId()); + adventureSettingsPacket.setPlayerFlags(playerFlags); + session.getUpstream().sendPacket(adventureSettingsPacket); + } + + private int setPlayerFlag(int flag, boolean value, int playerFlags) { + if (value) { + return playerFlags | flag; + } else { + return playerFlags & ~flag; + } + } +}