From e67d55d00d990e222edd03036743351239cb51cf Mon Sep 17 00:00:00 2001 From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> Date: Sat, 21 Jul 2018 12:58:48 +0100 Subject: [PATCH 1/4] Extend player profile API to support skin changes Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile --- ...-profile-API-to-support-skin-changes.patch | 29 ++++ ...-profile-API-to-support-skin-changes.patch | 163 ++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 Spigot-API-Patches/0126-Extend-player-profile-API-to-support-skin-changes.patch create mode 100644 Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch diff --git a/Spigot-API-Patches/0126-Extend-player-profile-API-to-support-skin-changes.patch b/Spigot-API-Patches/0126-Extend-player-profile-API-to-support-skin-changes.patch new file mode 100644 index 0000000000..6e851c0fe9 --- /dev/null +++ b/Spigot-API-Patches/0126-Extend-player-profile-API-to-support-skin-changes.patch @@ -0,0 +1,29 @@ +From c54292b8620985a83368e984581d4835604512e1 Mon Sep 17 00:00:00 2001 +From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> +Date: Sat, 21 Jul 2018 01:30:41 +0100 +Subject: [PATCH] Extend player profile API to support skin changes + +Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile + +diff --git a/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java +index e060c38a..98eade06 100644 +--- a/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java ++++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java +@@ -132,6 +132,14 @@ public interface PlayerProfile { + * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) + */ + boolean complete(boolean textures); ++ /** ++ * If this profile is not complete, then make the API call to complete it. ++ * This is a blocking operation and should be done asynchronously. ++ * ++ * Optionally will also fill textures. ++ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) ++ */ ++ boolean complete(boolean textures, boolean force); + + /** + * Whether or not this Profile has textures associated to it +-- +2.16.2.windows.1 + diff --git a/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch b/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch new file mode 100644 index 0000000000..ab79ee794b --- /dev/null +++ b/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch @@ -0,0 +1,163 @@ +From e709f6448451449a488b16d4039b25ff467cc956 Mon Sep 17 00:00:00 2001 +From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> +Date: Sat, 21 Jul 2018 01:30:30 +0100 +Subject: [PATCH] Extend player profile API to support skin changes + +Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile + +diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java +index 9ad5853d..dda24052 100644 +--- a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java ++++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java +@@ -170,17 +170,21 @@ public class CraftPlayerProfile implements PlayerProfile { + } + + public boolean complete(boolean textures) { ++ return complete(textures, false); ++ } ++ ++ public boolean complete(boolean textures, boolean force) { + MinecraftServer server = MinecraftServer.getServer(); + + boolean isOnlineMode = server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode); + boolean isCompleteFromCache = this.completeFromCache(true); +- if (isOnlineMode && (!isCompleteFromCache || textures && !hasTextures())) { ++ if ((isOnlineMode || force) && (!isCompleteFromCache || textures && !hasTextures())) { + GameProfile result = server.getSessionService().fillProfileProperties(profile, true); + if (result != null) { + this.profile = result; + } + } +- return profile.isComplete() && (!isOnlineMode || !textures || hasTextures()); ++ return profile.isComplete() && (!(isOnlineMode || force) || !textures || hasTextures()); + } + + private static void copyProfileProperties(GameProfile source, GameProfile target) { +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index dd78a87b..e3f7be28 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -135,6 +135,12 @@ public class WorldServer extends World implements IAsyncTaskHandler { + return this; + } + ++ // Paper start - Provide dimension number of world ++ public int getDimension() { ++ return dimension; ++ } ++ // Paper end ++ + // CraftBukkit start + @Override + public TileEntity getTileEntity(BlockPosition pos) { +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 210e3bc4..b0335684 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -101,6 +101,12 @@ public class CraftWorld implements World { + } + // Paper end + ++ // Paper start - Provide dimension number of world ++ public int getDimension() { ++ return world.dimension; ++ } ++ // Paper end ++ + private static final Random rand = new Random(); + + public CraftWorld(WorldServer world, ChunkGenerator gen, Environment env) { +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 6cbf429f..bd743be5 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -55,6 +55,7 @@ import org.bukkit.craftbukkit.CraftStatistic; + import org.bukkit.craftbukkit.CraftWorld; + import org.bukkit.craftbukkit.advancement.CraftAdvancement; + import org.bukkit.craftbukkit.advancement.CraftAdvancementProgress; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; + import org.bukkit.craftbukkit.map.CraftMapView; + import org.bukkit.craftbukkit.map.RenderData; + import org.bukkit.craftbukkit.scoreboard.CraftScoreboard; +@@ -1172,14 +1173,102 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + public void setPlayerProfile(PlayerProfile profile) { + EntityPlayer self = getHandle(); + self.setProfile(CraftPlayerProfile.asAuthlibCopy(profile)); +- List players = server.getServer().getPlayerList().players; +- for (EntityPlayer player : players) { +- player.getBukkitEntity().reregisterPlayer(self); +- } ++ refreshPlayer(); + } + public PlayerProfile getPlayerProfile() { + return new CraftPlayerProfile(this).clone(); + } ++ ++ private void refreshPlayer() { ++ int dimension = getWorld().getEnvironment().getId(); ++ Packet respawn = new PacketPlayOutRespawn(dimension, ((WorldServer)getHandle().getWorld()).worldData.getDifficulty(), ((WorldServer)getHandle().getWorld()).worldData.getType(), EnumGamemode.getById(getHandle().playerInteractManager.getGameMode().getId())); ++ Location l = getLocation(); ++ ++ Packet pos = new PacketPlayOutPosition(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch(), new HashSet<>(), 0); ++ Packet mainhand = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(getInventory().getItemInMainHand())); ++ Packet offhand = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.OFFHAND, CraftItemStack.asNMSCopy(getInventory().getItemInOffHand())); ++ Packet helm = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.HEAD, CraftItemStack.asNMSCopy(getInventory().getHelmet())); ++ Packet chest = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.CHEST, CraftItemStack.asNMSCopy(getInventory().getChestplate())); ++ Packet legs = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.LEGS, CraftItemStack.asNMSCopy(getInventory().getLeggings())); ++ Packet feet = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.FEET, CraftItemStack.asNMSCopy(getInventory().getBoots())); ++ Packet slot = new PacketPlayOutHeldItemSlot(getInventory().getHeldItemSlot()); ++ ++ for (Player pOnline : Bukkit.getOnlinePlayers()) { ++ EntityPlayer handle = ((CraftPlayer) pOnline).getHandle(); ++ PlayerConnection playerCon = handle.playerConnection; ++ if (pOnline.equals(this)) { ++ reregisterPlayer(handle); ++ ++ //Respawn the player then update their position and selected slot ++ handle.playerConnection.sendPacket(respawn); ++ handle.updateAbilities(); ++ handle.playerConnection.sendPacket(pos); ++ handle.playerConnection.sendPacket(slot); ++ ++ ((CraftPlayer) pOnline).updateScaledHealth(); ++ pOnline.updateInventory(); ++ ++ handle.triggerHealthUpdate(); ++ ++ if (pOnline.isOp()) { ++ pOnline.setOp(false); ++ pOnline.setOp(true); ++ } ++ continue; ++ } ++ if (pOnline.getWorld().equals(getWorld()) && pOnline.canSee(this) && isOnline()) { ++ PacketPlayOutEntityDestroy removeEntity = new PacketPlayOutEntityDestroy(new int[]{getEntityId()}); ++ PacketPlayOutNamedEntitySpawn addNamed = new PacketPlayOutNamedEntitySpawn(getHandle()); ++ ++ //Remove and reregister the player ++ handle.playerConnection.sendPacket(removeEntity); ++ ((CraftPlayer) pOnline).reregisterPlayer(this.getHandle()); ++ handle.playerConnection.sendPacket(addNamed); ++ ++ //Send hand items ++ handle.playerConnection.sendPacket(mainhand); ++ handle.playerConnection.sendPacket(offhand); ++ ++ //Send armor ++ handle.playerConnection.sendPacket(helm); ++ handle.playerConnection.sendPacket(chest); ++ handle.playerConnection.sendPacket(legs); ++ handle.playerConnection.sendPacket(feet); ++ } else { ++ //Just send player update ++ ((CraftPlayer) pOnline).reregisterPlayer(this.getHandle()); ++ } ++ } ++ ++ } + // Paper end + + public void removeDisconnectingPlayer(Player player) { +-- +2.16.2.windows.1 + From e5ea4656b23a82abca04d6dc20e478ed46983bf3 Mon Sep 17 00:00:00 2001 From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> Date: Sat, 21 Jul 2018 16:22:10 +0100 Subject: [PATCH 2/4] Extend player profile API to support skin changes Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile --- ...-profile-API-to-support-skin-changes.patch | 29 ---- ...-profile-API-to-support-skin-changes.patch | 128 ++++-------------- 2 files changed, 23 insertions(+), 134 deletions(-) delete mode 100644 Spigot-API-Patches/0126-Extend-player-profile-API-to-support-skin-changes.patch diff --git a/Spigot-API-Patches/0126-Extend-player-profile-API-to-support-skin-changes.patch b/Spigot-API-Patches/0126-Extend-player-profile-API-to-support-skin-changes.patch deleted file mode 100644 index 6e851c0fe9..0000000000 --- a/Spigot-API-Patches/0126-Extend-player-profile-API-to-support-skin-changes.patch +++ /dev/null @@ -1,29 +0,0 @@ -From c54292b8620985a83368e984581d4835604512e1 Mon Sep 17 00:00:00 2001 -From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> -Date: Sat, 21 Jul 2018 01:30:41 +0100 -Subject: [PATCH] Extend player profile API to support skin changes - -Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile - -diff --git a/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java -index e060c38a..98eade06 100644 ---- a/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java -+++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java -@@ -132,6 +132,14 @@ public interface PlayerProfile { - * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) - */ - boolean complete(boolean textures); -+ /** -+ * If this profile is not complete, then make the API call to complete it. -+ * This is a blocking operation and should be done asynchronously. -+ * -+ * Optionally will also fill textures. -+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) -+ */ -+ boolean complete(boolean textures, boolean force); - - /** - * Whether or not this Profile has textures associated to it --- -2.16.2.windows.1 - diff --git a/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch b/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch index ab79ee794b..64e753aa43 100644 --- a/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch +++ b/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch @@ -1,55 +1,10 @@ -From e709f6448451449a488b16d4039b25ff467cc956 Mon Sep 17 00:00:00 2001 +From ecf75579dcfbec00461841c87f96091901fe65fb Mon Sep 17 00:00:00 2001 From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> Date: Sat, 21 Jul 2018 01:30:30 +0100 Subject: [PATCH] Extend player profile API to support skin changes Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile -diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java -index 9ad5853d..dda24052 100644 ---- a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java -+++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java -@@ -170,17 +170,21 @@ public class CraftPlayerProfile implements PlayerProfile { - } - - public boolean complete(boolean textures) { -+ return complete(textures, false); -+ } -+ -+ public boolean complete(boolean textures, boolean force) { - MinecraftServer server = MinecraftServer.getServer(); - - boolean isOnlineMode = server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode); - boolean isCompleteFromCache = this.completeFromCache(true); -- if (isOnlineMode && (!isCompleteFromCache || textures && !hasTextures())) { -+ if ((isOnlineMode || force) && (!isCompleteFromCache || textures && !hasTextures())) { - GameProfile result = server.getSessionService().fillProfileProperties(profile, true); - if (result != null) { - this.profile = result; - } - } -- return profile.isComplete() && (!isOnlineMode || !textures || hasTextures()); -+ return profile.isComplete() && (!(isOnlineMode || force) || !textures || hasTextures()); - } - - private static void copyProfileProperties(GameProfile source, GameProfile target) { -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index dd78a87b..e3f7be28 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -135,6 +135,12 @@ public class WorldServer extends World implements IAsyncTaskHandler { - return this; - } - -+ // Paper start - Provide dimension number of world -+ public int getDimension() { -+ return dimension; -+ } -+ // Paper end -+ - // CraftBukkit start - @Override - public TileEntity getTileEntity(BlockPosition pos) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 210e3bc4..b0335684 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -68,7 +23,7 @@ index 210e3bc4..b0335684 100644 public CraftWorld(WorldServer world, ChunkGenerator gen, Environment env) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6cbf429f..bd743be5 100644 +index 6cbf429f..57f17120 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -55,6 +55,7 @@ import org.bukkit.craftbukkit.CraftStatistic; @@ -79,14 +34,10 @@ index 6cbf429f..bd743be5 100644 import org.bukkit.craftbukkit.map.CraftMapView; import org.bukkit.craftbukkit.map.RenderData; import org.bukkit.craftbukkit.scoreboard.CraftScoreboard; -@@ -1172,14 +1173,102 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - public void setPlayerProfile(PlayerProfile profile) { - EntityPlayer self = getHandle(); - self.setProfile(CraftPlayerProfile.asAuthlibCopy(profile)); -- List players = server.getServer().getPlayerList().players; -- for (EntityPlayer player : players) { -- player.getBukkitEntity().reregisterPlayer(self); -- } +@@ -1176,10 +1177,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + for (EntityPlayer player : players) { + player.getBukkitEntity().reregisterPlayer(self); + } + refreshPlayer(); } public PlayerProfile getPlayerProfile() { @@ -94,64 +45,31 @@ index 6cbf429f..bd743be5 100644 } + + private void refreshPlayer() { -+ int dimension = getWorld().getEnvironment().getId(); -+ Packet respawn = new PacketPlayOutRespawn(dimension, ((WorldServer)getHandle().getWorld()).worldData.getDifficulty(), ((WorldServer)getHandle().getWorld()).worldData.getType(), EnumGamemode.getById(getHandle().playerInteractManager.getGameMode().getId())); -+ Location l = getLocation(); ++ EntityPlayer entityplayer = getHandle(); + ++ Packet respawn = new PacketPlayOutRespawn(entityplayer.dimension, entityplayer.world.getDifficulty(), entityplayer.world.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode()); ++ Location l = getLocation(); + Packet pos = new PacketPlayOutPosition(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch(), new HashSet<>(), 0); -+ Packet mainhand = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(getInventory().getItemInMainHand())); -+ Packet offhand = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.OFFHAND, CraftItemStack.asNMSCopy(getInventory().getItemInOffHand())); -+ Packet helm = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.HEAD, CraftItemStack.asNMSCopy(getInventory().getHelmet())); -+ Packet chest = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.CHEST, CraftItemStack.asNMSCopy(getInventory().getChestplate())); -+ Packet legs = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.LEGS, CraftItemStack.asNMSCopy(getInventory().getLeggings())); -+ Packet feet = new PacketPlayOutEntityEquipment(getEntityId(), EnumItemSlot.FEET, CraftItemStack.asNMSCopy(getInventory().getBoots())); + Packet slot = new PacketPlayOutHeldItemSlot(getInventory().getHeldItemSlot()); + -+ for (Player pOnline : Bukkit.getOnlinePlayers()) { -+ EntityPlayer handle = ((CraftPlayer) pOnline).getHandle(); -+ PlayerConnection playerCon = handle.playerConnection; -+ if (pOnline.equals(this)) { -+ reregisterPlayer(handle); ++ EntityPlayer handle = getHandle(); ++ PlayerConnection playerCon = handle.playerConnection; ++ reregisterPlayer(handle); + -+ //Respawn the player then update their position and selected slot -+ handle.playerConnection.sendPacket(respawn); -+ handle.updateAbilities(); -+ handle.playerConnection.sendPacket(pos); -+ handle.playerConnection.sendPacket(slot); ++ //Respawn the player then update their position and selected slot ++ playerCon.sendPacket(respawn); ++ handle.updateAbilities(); ++ playerCon.sendPacket(pos); ++ playerCon.sendPacket(slot); + -+ ((CraftPlayer) pOnline).updateScaledHealth(); -+ pOnline.updateInventory(); ++ updateScaledHealth(); ++ this.updateInventory(); + -+ handle.triggerHealthUpdate(); ++ handle.triggerHealthUpdate(); + -+ if (pOnline.isOp()) { -+ pOnline.setOp(false); -+ pOnline.setOp(true); -+ } -+ continue; -+ } -+ if (pOnline.getWorld().equals(getWorld()) && pOnline.canSee(this) && isOnline()) { -+ PacketPlayOutEntityDestroy removeEntity = new PacketPlayOutEntityDestroy(new int[]{getEntityId()}); -+ PacketPlayOutNamedEntitySpawn addNamed = new PacketPlayOutNamedEntitySpawn(getHandle()); -+ -+ //Remove and reregister the player -+ handle.playerConnection.sendPacket(removeEntity); -+ ((CraftPlayer) pOnline).reregisterPlayer(this.getHandle()); -+ handle.playerConnection.sendPacket(addNamed); -+ -+ //Send hand items -+ handle.playerConnection.sendPacket(mainhand); -+ handle.playerConnection.sendPacket(offhand); -+ -+ //Send armor -+ handle.playerConnection.sendPacket(helm); -+ handle.playerConnection.sendPacket(chest); -+ handle.playerConnection.sendPacket(legs); -+ handle.playerConnection.sendPacket(feet); -+ } else { -+ //Just send player update -+ ((CraftPlayer) pOnline).reregisterPlayer(this.getHandle()); -+ } ++ if (this.isOp()) { ++ this.setOp(false); ++ this.setOp(true); + } + + } From 09f013532aa4a80b8322bb500c77797f0a3894e6 Mon Sep 17 00:00:00 2001 From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> Date: Sat, 21 Jul 2018 16:54:52 +0100 Subject: [PATCH 3/4] Remove unsed method --- ...-profile-API-to-support-skin-changes.patch | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch b/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch index 64e753aa43..d26ee3fbd9 100644 --- a/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch +++ b/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch @@ -1,27 +1,10 @@ -From ecf75579dcfbec00461841c87f96091901fe65fb Mon Sep 17 00:00:00 2001 +From 95e357f7dd549b278714a9ea76bf6d11d6c2b5fd Mon Sep 17 00:00:00 2001 From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> Date: Sat, 21 Jul 2018 01:30:30 +0100 Subject: [PATCH] Extend player profile API to support skin changes Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 210e3bc4..b0335684 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -101,6 +101,12 @@ public class CraftWorld implements World { - } - // Paper end - -+ // Paper start - Provide dimension number of world -+ public int getDimension() { -+ return world.dimension; -+ } -+ // Paper end -+ - private static final Random rand = new Random(); - - public CraftWorld(WorldServer world, ChunkGenerator gen, Environment env) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 6cbf429f..57f17120 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java From 7dd5837dd00436339a68e4412e71f7e677fd7cb8 Mon Sep 17 00:00:00 2001 From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> Date: Sat, 21 Jul 2018 18:17:54 +0100 Subject: [PATCH 4/4] Fixed more stuff --- ...-profile-API-to-support-skin-changes.patch | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch b/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch index d26ee3fbd9..78bf913b3a 100644 --- a/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch +++ b/Spigot-Server-Patches/0336-Extend-player-profile-API-to-support-skin-changes.patch @@ -1,4 +1,4 @@ -From 95e357f7dd549b278714a9ea76bf6d11d6c2b5fd Mon Sep 17 00:00:00 2001 +From 8a9ff94f0db13f56873de8e6f555bc7893cffc31 Mon Sep 17 00:00:00 2001 From: NickAcPT <32451103+NickAcPT@users.noreply.github.com> Date: Sat, 21 Jul 2018 01:30:30 +0100 Subject: [PATCH] Extend player profile API to support skin changes @@ -6,18 +6,10 @@ Subject: [PATCH] Extend player profile API to support skin changes Added code that refreshes the player's skin by sending packets with a special order, telling the client to respawn the player and re-apply the game profile diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6cbf429f..57f17120 100644 +index 6cbf429f..01335b6b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -55,6 +55,7 @@ import org.bukkit.craftbukkit.CraftStatistic; - import org.bukkit.craftbukkit.CraftWorld; - import org.bukkit.craftbukkit.advancement.CraftAdvancement; - import org.bukkit.craftbukkit.advancement.CraftAdvancementProgress; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; - import org.bukkit.craftbukkit.map.CraftMapView; - import org.bukkit.craftbukkit.map.RenderData; - import org.bukkit.craftbukkit.scoreboard.CraftScoreboard; -@@ -1176,10 +1177,41 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1176,10 +1176,38 @@ public class CraftPlayer extends CraftHumanEntity implements Player { for (EntityPlayer player : players) { player.getBukkitEntity().reregisterPlayer(self); } @@ -30,20 +22,17 @@ index 6cbf429f..57f17120 100644 + private void refreshPlayer() { + EntityPlayer entityplayer = getHandle(); + -+ Packet respawn = new PacketPlayOutRespawn(entityplayer.dimension, entityplayer.world.getDifficulty(), entityplayer.world.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode()); -+ Location l = getLocation(); -+ Packet pos = new PacketPlayOutPosition(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch(), new HashSet<>(), 0); -+ Packet slot = new PacketPlayOutHeldItemSlot(getInventory().getHeldItemSlot()); ++ Location loc = getLocation(); + + EntityPlayer handle = getHandle(); -+ PlayerConnection playerCon = handle.playerConnection; ++ PlayerConnection connection = handle.playerConnection; + reregisterPlayer(handle); + + //Respawn the player then update their position and selected slot -+ playerCon.sendPacket(respawn); ++ connection.sendPacket(new PacketPlayOutRespawn(entityplayer.dimension, entityplayer.world.getDifficulty(), entityplayer.world.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode())); + handle.updateAbilities(); -+ playerCon.sendPacket(pos); -+ playerCon.sendPacket(slot); ++ connection.sendPacket(new PacketPlayOutPosition(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), new HashSet<>(), 0)); ++ connection.sendPacket(new PacketPlayOutHeldItemSlot(getInventory().getHeldItemSlot())); + + updateScaledHealth(); + this.updateInventory();