Paper/patches/server/0183-Player.setPlayerProfile-API.patch

134 lines
7.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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 00ef714294b6cce5fec7613eed4ba228a48e3e11..67b300574655854249c1f7440f56a6e8f0fad351 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -341,12 +341,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(ServerLoginPacketListenerImpl.this.gameProfile);
AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId, profile);
server.getPluginManager().callEvent(asyncEvent);
profile = asyncEvent.getPlayerProfile();
- profile.complete();
- gameProfile = CraftPlayerProfile.asAuthlibCopy(profile);
+ profile.complete(true);
+ ServerLoginPacketListenerImpl.this.gameProfile = 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 a182c78c3718a6b8f56578c5e6b35ce5742046fe..85b50297d92c45872942effb770d0e85d864681e 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -171,7 +171,7 @@ public abstract class Player extends LivingEntity {
protected int enchantmentSeed;
protected final float defaultFlySpeed = 0.02F;
private int lastLevelUpTime;
- private final GameProfile gameProfile;
+ public GameProfile gameProfile; // Paper - private->public
private boolean reducedDebugInfo;
private ItemStack lastItemInMainHand;
private final ItemCooldowns cooldowns;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index d6f9fe4ebc034263169f3333922ad90fe4fcee69..a9bd48e4670aa44a964891c25cd147c006081b60 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -70,6 +70,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.saveddata.maps.MapDecoration;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
@@ -1351,8 +1352,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
this.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(this.getHandle());
@@ -1393,8 +1399,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
this.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
this.getHandle().connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, other));
@@ -1403,6 +1414,50 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
entry.updatePlayer(this.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.gameProfile = com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile);
+ if (!self.sentListPacket) {
+ return;
+ }
+ List<ServerPlayer> 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(), java.util.Collections.emptySet(), 0, false));
+ net.minecraft.server.MinecraftServer.getServer().getPlayerList().sendAllPlayerInfo(handle);
+
+ if (this.isOp()) {
+ this.setOp(false);
+ this.setOp(true);
+ }
+ }
+ // Paper end
public void removeDisconnectingPlayer(Player player) {
this.hiddenPlayers.remove(player.getUniqueId());