diff --git a/README.md b/README.md index 65a1261bd..a21a1b6c9 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Build Status](https://ci.opencollab.dev/job/Geyser/job/master/badge/icon)](https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/master/) [![Discord](https://img.shields.io/discord/613163671870242838.svg?color=%237289da&label=discord)](http://discord.geysermc.org/) -[![HitCount](http://hits.dwyl.io/Geyser/GeyserMC.svg)](http://hits.dwyl.io/Geyser/GeyserMC) +[![HitCount](http://hits.dwyl.com/Geyser/GeyserMC.svg)](http://hits.dwyl.com/Geyser/GeyserMC) [![Crowdin](https://badges.crowdin.net/geyser/localized.svg)](https://translate.geysermc.org/) Geyser is a bridge between Minecraft: Bedrock Edition and Minecraft: Java Edition, closing the gap from those wanting to play true cross-platform. diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 5e279c121..3cb95391d 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -62,6 +62,7 @@ import org.geysermc.floodgate.crypto.AesCipher; import org.geysermc.floodgate.crypto.AesKeyProducer; import org.geysermc.floodgate.crypto.Base64Topping; import org.geysermc.floodgate.crypto.FloodgateCipher; +import org.jetbrains.annotations.Contract; import javax.naming.directory.Attribute; import javax.naming.directory.InitialDirContext; @@ -372,9 +373,14 @@ public class GeyserConnector { * @param uuid the uuid * @return the player or null if there is no player online with this UUID */ + @Contract("null -> null") public GeyserSession getPlayerByUuid(UUID uuid) { + if (uuid == null) { + return null; + } + for (GeyserSession session : players) { - if (session.getPlayerEntity().getUuid().equals(uuid)) { + if (uuid.equals(session.getPlayerEntity().getUuid())) { return session; } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/player/SkullPlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/player/SkullPlayerEntity.java index 97f6f15c6..3f8d9ea93 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/player/SkullPlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/player/SkullPlayerEntity.java @@ -28,10 +28,14 @@ package org.geysermc.connector.entity.player; import com.github.steveice10.mc.auth.data.GameProfile; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.protocol.bedrock.data.PlayerPermission; +import com.nukkitx.protocol.bedrock.data.command.CommandPermission; import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket; import lombok.Getter; import lombok.Setter; +import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; /** @@ -61,6 +65,33 @@ public class SkullPlayerEntity extends PlayerEntity { metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true); // Until the skin is loaded } + /** + * Overwritten so each entity doesn't check for a linked entity + */ + @Override + public void spawnEntity(GeyserSession session) { + AddPlayerPacket addPlayerPacket = new AddPlayerPacket(); + addPlayerPacket.setUuid(getUuid()); + addPlayerPacket.setUsername(getUsername()); + addPlayerPacket.setRuntimeEntityId(geyserId); + addPlayerPacket.setUniqueEntityId(geyserId); + addPlayerPacket.setPosition(position.clone().sub(0, EntityType.PLAYER.getOffset(), 0)); + addPlayerPacket.setRotation(getBedrockRotation()); + addPlayerPacket.setMotion(motion); + addPlayerPacket.setHand(hand); + addPlayerPacket.getAdventureSettings().setCommandPermission(CommandPermission.NORMAL); + addPlayerPacket.getAdventureSettings().setPlayerPermission(PlayerPermission.MEMBER); + addPlayerPacket.setDeviceId(""); + addPlayerPacket.setPlatformChatId(""); + addPlayerPacket.getMetadata().putAll(metadata); + + valid = true; + session.sendUpstreamPacket(addPlayerPacket); + + updateEquipment(session); + updateBedrockAttributes(session); + } + public void despawnEntity(GeyserSession session, Vector3i position) { this.despawnEntity(session); session.getSkullCache().remove(position, this); diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 253088bba..767a61acd 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -98,7 +98,6 @@ import org.geysermc.cumulus.util.FormBuilder; import org.geysermc.floodgate.crypto.FloodgateCipher; import org.geysermc.floodgate.util.BedrockData; -import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; @@ -672,7 +671,16 @@ public class GeyserSession implements CommandSender { return; } connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.connect", authData.getName(), protocol.getProfile().getName(), remoteAddress)); - playerEntity.setUuid(protocol.getProfile().getId()); + UUID uuid = protocol.getProfile().getId(); + if (uuid == null) { + // Set what our UUID *probably* is going to be + if (remoteAuthType == AuthType.FLOODGATE) { + uuid = new UUID(0, Long.parseLong(authData.getXboxUUID())); + } else { + uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + protocol.getProfile().getName()).getBytes(StandardCharsets.UTF_8)); + } + } + playerEntity.setUuid(uuid); playerEntity.setUsername(protocol.getProfile().getName()); String locale = clientData.getLanguageCode(); diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java index a2eb60053..4d6750bc0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java @@ -59,6 +59,7 @@ public class EntityCache { public EntityCache(GeyserSession session) { this.session = session; + cachedPlayerEntityLinks.defaultReturnValue(-1L); } public void spawnEntity(Entity entity) { @@ -100,6 +101,9 @@ public class EntityCache { for (Entity entity : entities) { session.getEntityCache().removeEntity(entity, false); } + + // As a precaution + cachedPlayerEntityLinks.clear(); } public Entity getEntityByGeyserId(long geyserId) { @@ -160,7 +164,7 @@ public class EntityCache { } public long getCachedPlayerEntityLink(long playerId) { - return cachedPlayerEntityLinks.getOrDefault(playerId, -1); + return cachedPlayerEntityLinks.remove(playerId); } public void addCachedPlayerEntityLink(long playerId, long linkedEntityId) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java index b7d6c5e06..da9ce64ff 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java @@ -47,9 +47,11 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator