diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 7c518abc2..714bd5aed 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -50,6 +50,7 @@ import java.text.DecimalFormat; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -62,7 +63,7 @@ public class GeyserConnector { public static final String NAME = "Geyser"; public static final String VERSION = "1.0-SNAPSHOT"; - private final Map players = new HashMap<>(); + private final Map players = new HashMap<>(); private static GeyserConnector instance; @@ -188,15 +189,11 @@ public class GeyserConnector { } public void addPlayer(GeyserSession player) { - players.put(player.getAuthData().getName(), player); players.put(player.getAuthData().getUUID(), player); - players.put(player.getSocketAddress(), player); } public void removePlayer(GeyserSession player) { - players.remove(player.getAuthData().getName()); players.remove(player.getAuthData().getUUID()); - players.remove(player.getSocketAddress()); } public static GeyserConnector start(PlatformType platformType, IGeyserBootstrap bootstrap) { diff --git a/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java new file mode 100644 index 000000000..5a0cac8f4 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020 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; +import com.nukkitx.protocol.bedrock.data.EntityData; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.translators.block.BlockTranslator; + +public class FallingBlockEntity extends Entity { + + public FallingBlockEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, int javaId) { + super(entityId, geyserId, entityType, position, motion, rotation); + + this.metadata.put(EntityData.VARIANT, BlockTranslator.getBedrockBlockId(javaId)); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java index dbf759f58..b4c958904 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java @@ -25,12 +25,32 @@ package org.geysermc.connector.entity.living.animal.horse; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket; import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.block.BlockTranslator; public class LlamaEntity extends ChestedHorseEntity { public LlamaEntity(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) { + // Strength + if (entityMetadata.getId() == 19) { + metadata.put(EntityData.STRENGTH, entityMetadata.getValue()); + } + // Color of the llama + if (entityMetadata.getId() == 21) { + metadata.put(EntityData.VARIANT, entityMetadata.getValue()); + } + super.updateBedrockMetadata(entityMetadata, session); + } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java new file mode 100644 index 000000000..5e591bc7c --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019-2020 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.living.animal.horse; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +public class TraderLlamaEntity extends LlamaEntity { + + public TraderLlamaEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } + + @Override + public void spawnEntity(GeyserSession session) { + // The trader llama is a separate entity from the llama in Java but a normal llama with extra metadata in Bedrock. + AddEntityPacket addEntityPacket = new AddEntityPacket(); + addEntityPacket.setIdentifier("minecraft:llama"); + addEntityPacket.setRuntimeEntityId(geyserId); + addEntityPacket.setUniqueEntityId(geyserId); + addEntityPacket.setPosition(position); + addEntityPacket.setMotion(motion); + addEntityPacket.setRotation(getBedrockRotation()); + addEntityPacket.setEntityType(entityType.getType()); + addEntityPacket.getMetadata().putAll(metadata); + // Here's the difference + addEntityPacket.getMetadata().put(EntityData.MARK_VARIANT, 1); + + valid = true; + session.getUpstream().sendPacket(addEntityPacket); + + session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")"); + } + +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java index f6af511cd..500aa1a2e 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java +++ b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java @@ -31,10 +31,7 @@ import org.geysermc.connector.entity.living.*; import org.geysermc.connector.entity.living.animal.*; import org.geysermc.connector.entity.living.animal.tameable.CatEntity; import org.geysermc.connector.entity.living.animal.tameable.TameableEntity; -import org.geysermc.connector.entity.living.animal.horse.AbstractHorseEntity; -import org.geysermc.connector.entity.living.animal.horse.ChestedHorseEntity; -import org.geysermc.connector.entity.living.animal.horse.HorseEntity; -import org.geysermc.connector.entity.living.animal.horse.LlamaEntity; +import org.geysermc.connector.entity.living.animal.horse.*; import org.geysermc.connector.entity.living.animal.tameable.WolfEntity; import org.geysermc.connector.entity.living.monster.*; import org.geysermc.connector.entity.living.monster.raid.AbstractIllagerEntity; @@ -64,7 +61,7 @@ public enum EntityType { ZOMBIE_HORSE(AbstractHorseEntity.class, 27, 1.6f, 1.3965f), POLAR_BEAR(PolarBearEntity.class, 28, 1.4f, 1.3f), LLAMA(LlamaEntity.class, 29, 1.87f, 0.9f), - TRADER_LLAMA(LlamaEntity.class, 29, 1.187f, 0.9f), + TRADER_LLAMA(TraderLlamaEntity.class, 29, 1.187f, 0.9f), PARROT(TameableEntity.class, 30, 0.9f, 0.5f), DOLPHIN(WaterEntity.class, 31, 0.6f, 0.9f), ZOMBIE(ZombieEntity.class, 32, 1.8f, 0.6f, 0.6f, 1.62f), @@ -103,7 +100,7 @@ public enum EntityType { PLAYER(PlayerEntity.class, 63, 1.8f, 0.6f, 0.6f, 1.62f), ITEM(ItemEntity.class, 64, 0.25f, 0.25f), TNT(Entity.class, 65, 0.98f, 0.98f), - FALLING_BLOCK(Entity.class, 66, 0.98f, 0.98f), + FALLING_BLOCK(FallingBlockEntity.class, 66, 0.98f, 0.98f), MOVING_BLOCK(Entity.class, 67, 0f), EXPERIENCE_BOTTLE(ThrowableEntity.class, 68, 0.25f, 0.25f), EXPERIENCE_ORB(ExpOrbEntity.class, 69, 0f), diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java index c782e099a..98846e882 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java @@ -177,6 +177,10 @@ public class BlockTranslator { return JAVA_TO_BEDROCK_BLOCK_MAP.get(state.getId()); } + public static int getBedrockBlockId(int javaId) { + return JAVA_TO_BEDROCK_BLOCK_MAP.get(javaId); + } + public static BlockState getJavaBlockState(int bedrockId) { return BEDROCK_TO_JAVA_BLOCK_MAP.get(bedrockId); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java index 15741c98e..c3998f870 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java @@ -28,7 +28,9 @@ package org.geysermc.connector.network.translators.java.entity.spawn; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import com.github.steveice10.mc.protocol.data.game.entity.type.object.FallingBlockData; import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.entity.FallingBlockEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -59,12 +61,18 @@ public class JavaSpawnObjectTranslator extends PacketTranslator entityClass = type.getEntityClass(); try { - Constructor entityConstructor = entityClass.getConstructor(long.class, long.class, EntityType.class, - Vector3f.class, Vector3f.class, Vector3f.class); + Entity entity; + if (packet.getType() == ObjectType.FALLING_BLOCK) { + entity = new FallingBlockEntity(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), + type, position, motion, rotation, ((FallingBlockData) packet.getData()).getId()); + } else { + Constructor entityConstructor = entityClass.getConstructor(long.class, long.class, EntityType.class, + Vector3f.class, Vector3f.class, Vector3f.class); - Entity entity = entityConstructor.newInstance(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), - type, position, motion, rotation - ); + entity = entityConstructor.newInstance(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), + type, position, motion, rotation + ); + } session.getEntityCache().spawnEntity(entity); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex) { ex.printStackTrace(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java index ccf3e2090..28022c16d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java @@ -40,7 +40,7 @@ public class JavaMapDataTranslator extends PacketTranslator ClientboundMapItemDataPacket mapItemDataPacket = new ClientboundMapItemDataPacket(); mapItemDataPacket.setUniqueMapId(packet.getMapId()); - mapItemDataPacket.setDimensionId(session.getLastDimPacket().getDimension()); + mapItemDataPacket.setDimensionId(session.getPlayerEntity().getDimension()); mapItemDataPacket.setLocked(packet.isLocked()); mapItemDataPacket.setScale(packet.getScale());