From db6b5b45ff13428a65ca43622a1a1f5b060dd41f Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Thu, 28 Dec 2023 00:22:44 +0100 Subject: [PATCH] Fix long loading screen when refreshing skins (#10026) Send `ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START` when refreshing players after player profile changes. --- ...-CauldronLevelChange-on-initial-fill.patch | 40 ------------------- ...tem-locations-dropped-from-campfires.patch | 14 +++---- .../server/Player.setPlayerProfile-API.patch | 34 ++++++++++++---- 3 files changed, 32 insertions(+), 56 deletions(-) diff --git a/patches/server/Fire-CauldronLevelChange-on-initial-fill.patch b/patches/server/Fire-CauldronLevelChange-on-initial-fill.patch index 803e7b70cd..e631e1e3ca 100644 --- a/patches/server/Fire-CauldronLevelChange-on-initial-fill.patch +++ b/patches/server/Fire-CauldronLevelChange-on-initial-fill.patch @@ -6,46 +6,6 @@ Subject: [PATCH] Fire CauldronLevelChange on initial fill Also don't fire level events or game events if stalactite drip is cancelled -diff --git a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java -+++ b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java -@@ -0,0 +0,0 @@ public interface CauldronInteraction { - } else { - if (!world.isClientSide) { - // CraftBukkit start -- if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, Blocks.WATER_CAULDRON.defaultBlockState(), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY)) { -+ if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, Blocks.WATER_CAULDRON.defaultBlockState(), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - return InteractionResult.SUCCESS; - } - // CraftBukkit end -@@ -0,0 +0,0 @@ public interface CauldronInteraction { - if ((Integer) iblockdata.getValue(LayeredCauldronBlock.LEVEL) != 3 && PotionUtils.getPotion(itemstack) == Potions.WATER) { - if (!world.isClientSide) { - // CraftBukkit start -- if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata.cycle(LayeredCauldronBlock.LEVEL), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY)) { -+ if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata.cycle(LayeredCauldronBlock.LEVEL), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - return InteractionResult.SUCCESS; - } - // CraftBukkit end -@@ -0,0 +0,0 @@ public interface CauldronInteraction { - } else { - if (!world.isClientSide) { - // CraftBukkit start -- if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.CAULDRON.defaultBlockState(), player, CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL)) { -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.CAULDRON.defaultBlockState(), player, CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL, false)) { // Paper - return InteractionResult.SUCCESS; - } - // CraftBukkit end -@@ -0,0 +0,0 @@ public interface CauldronInteraction { - static InteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent) { - if (!world.isClientSide) { - // CraftBukkit start -- if (!LayeredCauldronBlock.changeLevel(state, world, pos, state, player, CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY)) { -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, state, player, CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY, false)) { // Paper - return InteractionResult.SUCCESS; - } - // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java diff --git a/patches/server/Fix-item-locations-dropped-from-campfires.patch b/patches/server/Fix-item-locations-dropped-from-campfires.patch index 72b68d5023..e2c2851318 100644 --- a/patches/server/Fix-item-locations-dropped-from-campfires.patch +++ b/patches/server/Fix-item-locations-dropped-from-campfires.patch @@ -4,7 +4,6 @@ Date: Sat, 3 Oct 2020 20:32:25 -0500 Subject: [PATCH] Fix item locations dropped from campfires Fixes #4259 by not flooring the blockposition among other weirdness -Vanilla Issue: MC-267622 diff --git a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -15,14 +14,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 itemstack1 = CraftItemStack.asNMSCopy(result); // CraftBukkit end - Containers.dropItemStack(world, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), itemstack1); -+ // Paper start -+ double deviation = 0.05F * RandomSource.GAUSSIAN_SPREAD_FACTOR; -+ while (!itemstack1.isEmpty()) { -+ net.minecraft.world.entity.item.ItemEntity droppedItem = new net.minecraft.world.entity.item.ItemEntity(world, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, itemstack1.split(world.random.nextInt(21) + 10)); -+ droppedItem.setDeltaMovement(world.random.triangle(0.0D, deviation), world.random.triangle(0.2D, deviation), world.random.triangle(0.0D, deviation)); -+ world.addFreshEntity(droppedItem); -+ } -+ // Paper end ++ // Paper start ++ net.minecraft.world.entity.item.ItemEntity droppedItem = new net.minecraft.world.entity.item.ItemEntity(world, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, itemstack1.split(world.random.nextInt(21) + 10)); ++ droppedItem.setDeltaMovement(world.random.nextGaussian() * 0.05D, world.random.nextGaussian() * 0.05D + 0.2D, world.random.nextGaussian() * 0.05D); ++ world.addFreshEntity(droppedItem); ++ // Paper end campfire.items.set(i, ItemStack.EMPTY); world.sendBlockUpdated(pos, state, state, 3); world.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state)); diff --git a/patches/server/Player.setPlayerProfile-API.patch b/patches/server/Player.setPlayerProfile-API.patch index 09f3f82586..486c7781ff 100644 --- a/patches/server/Player.setPlayerProfile-API.patch +++ b/patches/server/Player.setPlayerProfile-API.patch @@ -39,6 +39,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 gameprofile = com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile); playerName = gameprofile.getName(); uniqueId = gameprofile.getId(); +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -0,0 +0,0 @@ public abstract class PlayerList { + } + + public void sendPlayerPermissionLevel(ServerPlayer player) { ++ // Paper start - avoid recalculating permissions if possible ++ this.sendPlayerPermissionLevel(player, true); ++ } ++ ++ public void sendPlayerPermissionLevel(ServerPlayer player, boolean recalculatePermissions) { ++ // Paper end - avoid recalculating permissions if possible + GameProfile gameprofile = player.getGameProfile(); + int i = this.server.getProfilePermissions(gameprofile); + +- this.sendPlayerPermissionLevel(player, i); ++ this.sendPlayerPermissionLevel(player, i, recalculatePermissions); // Paper - avoid recalculating permissions if possible + } + + public void tick() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -179,21 +201,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + //Respawn the player then update their position and selected slot + ServerLevel worldserver = handle.serverLevel(); -+ connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(new net.minecraft.network.protocol.game.CommonPlayerSpawnInfo(worldserver.dimensionTypeId(), worldserver.dimension(), net.minecraft.world.level.biome.BiomeManager.obfuscateSeed(worldserver.getSeed()), handle.gameMode.getGameModeForPlayer(), handle.gameMode.getPreviousGameModeForPlayer(), worldserver.isDebug(), worldserver.isFlat(), handle.getLastDeathLocation(), handle.getPortalCooldown()), net.minecraft.network.protocol.game.ClientboundRespawnPacket.KEEP_ALL_DATA)); ++ connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(handle.createCommonSpawnInfo(worldserver), net.minecraft.network.protocol.game.ClientboundRespawnPacket.KEEP_ALL_DATA)); + handle.onUpdateAbilities(); + connection.internalTeleport(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), java.util.Collections.emptySet()); -+ net.minecraft.server.MinecraftServer.getServer().getPlayerList().sendAllPlayerInfo(handle); ++ net.minecraft.server.players.PlayerList playerList = handle.server.getPlayerList(); ++ playerList.sendPlayerPermissionLevel(handle, false); ++ playerList.sendLevelInfo(handle, worldserver); ++ playerList.sendAllPlayerInfo(handle); + + // Resend their XP and effects because the respawn packet resets it + connection.send(new net.minecraft.network.protocol.game.ClientboundSetExperiencePacket(handle.experienceProgress, handle.totalExperience, handle.experienceLevel)); + for (net.minecraft.world.effect.MobEffectInstance mobEffect : handle.getActiveEffects()) { + connection.send(new net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket(handle.getId(), mobEffect)); + } -+ -+ if (this.isOp()) { -+ this.setOp(false); -+ this.setOp(true); -+ } + } + // Paper end