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 e5be45ac86907c1f8cc154bd38fd624a2320180f..0aa3a154d68f00edcc09b947a24b2b59b1e135e6 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -54,7 +54,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener public final Connection connection; private ServerLoginPacketListenerImpl.State state; private int tick; - private GameProfile gameProfile; + private GameProfile gameProfile; private void setGameProfile(final GameProfile profile) { this.gameProfile = profile; } private GameProfile getGameProfile() { return this.gameProfile; } // Paper - OBFHELPER private final String serverId; private SecretKey secretKey; private ServerPlayer delayedAcceptPlayer; @@ -318,12 +318,12 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener final org.bukkit.craftbukkit.CraftServer server = ServerLoginPacketListenerImpl.this.server.server; // Paper start - PlayerProfile profile = Bukkit.createProfile(uniqueId, playerName); + PlayerProfile profile = CraftPlayerProfile.asBukkitMirror(getGameProfile()); AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId, profile); server.getPluginManager().callEvent(asyncEvent); profile = asyncEvent.getPlayerProfile(); - profile.complete(); - gameProfile = CraftPlayerProfile.asAuthlibCopy(profile); + profile.complete(true); + setGameProfile(CraftPlayerProfile.asAuthlib(profile)); playerName = gameProfile.getName(); uniqueId = gameProfile.getId(); // Paper end diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java index 63871a3a1981b2e8c7ad74214196e35684acb584..c4aa824d03de952fe6b306e539baa47af979add1 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -159,7 +159,7 @@ public abstract class Player extends LivingEntity { protected int enchantmentSeed; protected final float defaultFlySpeed = 0.02F; private int lastLevelUpTime; - private final GameProfile gameProfile; + private GameProfile gameProfile; public final void setProfile(final GameProfile profile) { this.gameProfile = profile; } // Paper - OBFHELPER private ItemStack lastItemInMainHand; private final ItemCooldowns cooldowns; @Nullable diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index efdcb8dac8db15c4bbaed84a7861ce98339e516a..9d853733ff9054cc48925e22c8bb3c8d9b898808 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -67,6 +67,7 @@ import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.GameType; +import net.minecraft.world.level.biome.BiomeManager; import net.minecraft.world.level.block.entity.SignBlockEntity; import net.minecraft.world.level.saveddata.maps.MapDecoration; import net.minecraft.world.phys.Vec3; @@ -1307,8 +1308,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { hiddenPlayers.put(player.getUniqueId(), hidingPlugins); // Remove this player from the hidden player's EntityTrackerEntry - ChunkMap tracker = ((ServerLevel) entity.level).getChunkSource().chunkMap; + // Paper start ServerPlayer other = ((CraftPlayer) player).getHandle(); + unregisterPlayer(other); + } + private void unregisterPlayer(ServerPlayer other) { + ChunkMap tracker = ((ServerLevel) entity.level).getChunkSource().chunkMap; + // Paper end ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId()); if (entry != null) { entry.removePlayer(getHandle()); @@ -1349,8 +1355,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } hiddenPlayers.remove(player.getUniqueId()); - ChunkMap tracker = ((ServerLevel) entity.level).getChunkSource().chunkMap; + // Paper start ServerPlayer other = ((CraftPlayer) player).getHandle(); + registerPlayer(other); + } + private void registerPlayer(ServerPlayer other) { + ChunkMap tracker = ((ServerLevel) entity.level).getChunkSource().chunkMap; + // Paper end getHandle().connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, other)); @@ -1359,6 +1370,50 @@ public class CraftPlayer extends CraftHumanEntity implements Player { entry.updatePlayer(getHandle()); } } + // Paper start + private void reregisterPlayer(ServerPlayer player) { + if (!hiddenPlayers.containsKey(player.getUUID())) { + unregisterPlayer(player); + registerPlayer(player); + } + } + public void setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile profile) { + ServerPlayer self = getHandle(); + self.setProfile(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(); + } + + 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.dimensionType(), worldserver.dimension(), BiomeManager.obfuscateSeed(worldserver.getSeed()), handle.gameMode.getGameModeForPlayer(), handle.gameMode.getPreviousGameModeForPlayer(), worldserver.isDebug(), worldserver.isFlat(), true)); + handle.onUpdateAbilities(); + connection.send(new net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), new HashSet<>(), 0)); + net.minecraft.server.MinecraftServer.getServer().getPlayerList().sendAllPlayerInfo(handle); + + if (this.isOp()) { + this.setOp(false); + this.setOp(true); + } + } + // Paper end public void removeDisconnectingPlayer(Player player) { hiddenPlayers.remove(player.getUniqueId());