From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 18 Mar 2018 12:29:48 -0400 Subject: [PATCH] Player.setPlayerProfile API This can be useful for changing name or skins after a player has logged in. diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java index 9a7fe61d7de80eaf044c202e1ed13d9e4b59622a..ef09f5f42a89f767060f015af27269ad496d08c7 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -370,11 +370,11 @@ public class ServerLoginPacketListenerImpl implements TickablePacketListener, Se final org.bukkit.craftbukkit.CraftServer server = ServerLoginPacketListenerImpl.this.server.server; // Paper start - com.destroystokyo.paper.profile.PlayerProfile profile = org.bukkit.Bukkit.createProfile(uniqueId, playerName); + com.destroystokyo.paper.profile.PlayerProfile profile = com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitMirror(ServerLoginPacketListenerImpl.this.gameProfile); AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId, profile); server.getPluginManager().callEvent(asyncEvent); profile = asyncEvent.getPlayerProfile(); - profile.complete(); + profile.complete(true); // Paper - setPlayerProfileAPI gameProfile = com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile); playerName = gameProfile.getName(); uniqueId = gameProfile.getId(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 299f2a8c45462d8070312c98554dbcc05298c681..31bcabd4c6ac3aa261c439a154ba7eb0f8caa0b8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -75,6 +75,7 @@ import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.level.GameType; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.biome.BiomeManager; import net.minecraft.world.level.block.entity.SignBlockEntity; import net.minecraft.world.level.border.BorderChangeListener; import net.minecraft.world.level.saveddata.maps.MapDecoration; @@ -201,11 +202,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return server.getPlayer(getUniqueId()) != null; } - @Override - public PlayerProfile getPlayerProfile() { - return new CraftPlayerProfile(this.getProfile()); - } - @Override public InetSocketAddress getAddress() { if (this.getHandle().connection == null) return null; @@ -1498,8 +1494,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.hiddenEntities.put(entity.getUniqueId(), hidingPlugins); // Remove this entity from the hidden player's EntityTrackerEntry - ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; + // Paper start Entity other = ((CraftEntity) entity).getHandle(); + unregisterEntity(other); + + server.getPluginManager().callEvent(new PlayerHideEntityEvent(this, entity)); + } + private void unregisterEntity(Entity other) { + // Paper end + ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); if (entry != null) { entry.removePlayer(this.getHandle()); @@ -1512,8 +1515,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.REMOVE_PLAYER, otherPlayer)); } } - - server.getPluginManager().callEvent(new PlayerHideEntityEvent(this, entity)); } @Override @@ -1550,8 +1551,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } this.hiddenEntities.remove(entity.getUniqueId()); - ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; + // Paper start Entity other = ((CraftEntity) entity).getHandle(); + registerEntity(other); + + server.getPluginManager().callEvent(new PlayerShowEntityEvent(this, entity)); + } + private void registerEntity(Entity other) { + ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap; + // Paper end if (other instanceof ServerPlayer) { ServerPlayer otherPlayer = (ServerPlayer) other; @@ -1562,9 +1570,51 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (entry != null && !entry.seenBy.contains(this.getHandle().connection)) { entry.updatePlayer(this.getHandle()); } + } + // Paper start + private void reregisterPlayer(ServerPlayer player) { + if (!hiddenEntities.containsKey(player.getUUID())) { + unregisterEntity(player); + registerEntity(player); + } + } + public void setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile profile) { + ServerPlayer self = getHandle(); + self.gameProfile = com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile); + if (!self.sentListPacket) { + return; + } + List players = server.getServer().getPlayerList().players; + for (ServerPlayer player : players) { + player.getBukkitEntity().reregisterPlayer(self); + } + refreshPlayer(); + } + public com.destroystokyo.paper.profile.PlayerProfile getPlayerProfile() { + return new com.destroystokyo.paper.profile.CraftPlayerProfile(this).clone(); + } - server.getPluginManager().callEvent(new PlayerShowEntityEvent(this, entity)); + private void refreshPlayer() { + ServerPlayer handle = getHandle(); + + Location loc = getLocation(); + + ServerGamePacketListenerImpl connection = handle.connection; + reregisterPlayer(handle); + + //Respawn the player then update their position and selected slot + ServerLevel worldserver = handle.getLevel(); + connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(worldserver.dimensionTypeId(), worldserver.dimension(), BiomeManager.obfuscateSeed(worldserver.getSeed()), handle.gameMode.getGameModeForPlayer(), handle.gameMode.getPreviousGameModeForPlayer(), worldserver.isDebug(), worldserver.isFlat(), true, this.getHandle().getLastDeathLocation())); + handle.onUpdateAbilities(); + connection.internalTeleport(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), java.util.Collections.emptySet(), false); + net.minecraft.server.MinecraftServer.getServer().getPlayerList().sendAllPlayerInfo(handle); + + if (this.isOp()) { + this.setOp(false); + this.setOp(true); + } } + // Paper end public void onEntityRemove(Entity entity) { this.hiddenEntities.remove(entity.getUUID());