aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0184-Player.setPlayerProfile-API.patch
blob: 9590a80b71b2e3d60e2bf358d61a846e1e33480f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index f696e31ec286263c4d06d6897b3aef0fa50f8f34..51839994999b22251bd9e813f1e05ef8d7e97c0d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -71,6 +71,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;
@@ -1358,8 +1359,13 @@ 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);
+    }
+    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());
@@ -1408,8 +1414,13 @@ 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);
+    }
+    private void registerEntity(Entity other) {
+        ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap;
+        // Paper end
 
         if (other instanceof ServerPlayer) {
             ServerPlayer otherPlayer = (ServerPlayer) other;
@@ -1421,6 +1432,50 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
             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<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 onEntityRemove(Entity entity) {
         this.hiddenEntities.remove(entity.getUUID());