From 0b9ef3701efca60f746fbe9bb5d25292f0668b34 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 11 Jul 2022 11:56:41 -0700 Subject: [PATCH] Fix a bunch of vanilla bugs https://bugs.mojang.com/browse/MC-253721 wrong msg for opping multiple players https://bugs.mojang.com/browse/MC-248588 respect mob griefing gamerule for draining water cauldrons https://bugs.mojang.com/browse/MC-244739 play goat eating sound for last item in stack https://bugs.mojang.com/browse/MC-243057 ignore furnace fuel slot in recipe book click https://bugs.mojang.com/browse/MC-147659 Some witch huts spawn the incorrect cat Note: Marked as Won't Fix, makes 0 sense https://bugs.mojang.com/browse/MC-179072 Creepers do not defuse when switching from Survival to Creative/Spectator https://bugs.mojang.com/browse/MC-259571 Fix changeGameModeForPlayer to use gameModeForPlayer https://bugs.mojang.com/browse/MC-262422 Fix lightning being able to hit spectators https://bugs.mojang.com/browse/MC-263999 Fix mobs breaking doors not spawning block break particles https://bugs.mojang.com/browse/MC-210802 Fixes sheep eating blocks outside of ticking range https://bugs.mojang.com/browse/MC-123848 Fixes item frames dropping items above when pointing down https://bugs.mojang.com/browse/MC-174630 Fix secondary beacon effect remaining after switching effect https://bugs.mojang.com/browse/MC-153086 Fix the beacon deactivation sound always playing when broken https://bugs.mojang.com/browse/MC-200092 Fix yaw being ignored for a player's first spawn pos https://bugs.mojang.com/browse/MC-158900 Fix error when joining after tempban expired https://bugs.mojang.com/browse/MC-99075 Fix inventory desync within spawn protected area https://bugs.mojang.com/browse/MC-273635 Fix TrialSpawner forgets assigned mob when placed by player == AT == public net/minecraft/world/entity/Mob leashInfoTag public net/minecraft/server/level/ChunkMap anyPlayerCloseEnoughForSpawning(Lnet/minecraft/world/level/ChunkPos;)Z Co-authored-by: William Blake Galbreath Co-authored-by: Spottedleaf --- .../server/commands/DeOpCommands.java.patch | 11 +++ .../server/commands/OpCommand.java.patch | 11 +++ .../server/level/ServerLevel.java.patch | 20 ++++-- .../level/ServerPlayerGameMode.java.patch | 15 ++-- .../ServerGamePacketListenerImpl.java.patch | 37 ++++++---- .../server/players/PlayerList.java.patch | 68 +++++++++---------- .../entity/ai/goal/BreakDoorGoal.java.patch | 9 ++- .../entity/ai/goal/EatBlockGoal.java.patch | 16 ++++- .../world/entity/ai/goal/SwellGoal.java.patch | 17 +++++ .../world/entity/animal/goat/Goat.java.patch | 15 +++- .../entity/decoration/ItemFrame.java.patch | 22 +++++- .../world/entity/npc/CatSpawner.java.patch | 12 ++++ .../world/inventory/BeaconMenu.java.patch | 9 ++- .../block/LayeredCauldronBlock.java.patch | 5 +- .../AbstractFurnaceBlockEntity.java.patch | 17 ++++- .../block/entity/BeaconBlockEntity.java.patch | 12 ++-- .../trialspawner/TrialSpawner.java.patch | 9 +++ .../trialspawner/TrialSpawnerData.java.patch | 12 ++++ .../trialspawner/TrialSpawnerState.java.patch | 11 +++ .../portal/TeleportTransition.java.patch | 11 ++- 20 files changed, 256 insertions(+), 83 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/server/commands/DeOpCommands.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/server/commands/OpCommand.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/npc/CatSpawner.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java.patch diff --git a/paper-server/patches/sources/net/minecraft/server/commands/DeOpCommands.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/DeOpCommands.java.patch new file mode 100644 index 0000000000..5009b1bdcb --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/server/commands/DeOpCommands.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/commands/DeOpCommands.java ++++ b/net/minecraft/server/commands/DeOpCommands.java +@@ -35,7 +35,7 @@ + if (playerList.isOp(gameProfile)) { + playerList.deop(gameProfile); + i++; +- source.sendSuccess(() -> Component.translatable("commands.deop.success", targets.iterator().next().getName()), true); ++ source.sendSuccess(() -> Component.translatable("commands.deop.success", gameProfile.getName()), true); // Paper - fixes MC-253721 + } + } + diff --git a/paper-server/patches/sources/net/minecraft/server/commands/OpCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/OpCommand.java.patch new file mode 100644 index 0000000000..3ca43d3777 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/server/commands/OpCommand.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/commands/OpCommand.java ++++ b/net/minecraft/server/commands/OpCommand.java +@@ -46,7 +46,7 @@ + if (!playerList.isOp(gameProfile)) { + playerList.op(gameProfile); + i++; +- source.sendSuccess(() -> Component.translatable("commands.op.success", targets.iterator().next().getName()), true); ++ source.sendSuccess(() -> Component.translatable("commands.op.success", gameProfile.getName()), true); // Paper - fixes MC-253721 + } + } + diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index 31100bb6c5..50af3d074d 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -61,7 +61,7 @@ private int lastSpawnChunkRadius; final EntityTickList entityTickList = new EntityTickList(); public final PersistentEntitySectionManager entityManager; -@@ -214,53 +226,203 @@ +@@ -214,54 +226,204 @@ private final boolean tickTime; private final RandomSequences randomSequences; @@ -136,7 +136,7 @@ + + int minChunkX = minBlockX >> 4; + int minChunkZ = minBlockZ >> 4; - ++ + int maxChunkX = maxBlockX >> 4; + int maxChunkZ = maxBlockZ >> 4; + @@ -227,7 +227,7 @@ + boolean flag2 = minecraftserver.forceSynchronousWrites(); + DataFixer datafixer = minecraftserver.getFixerUpper(); + EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); -+ + this.entityManager = new PersistentEntitySectionManager<>(Entity.class, new ServerLevel.EntityCallbacks(), entitypersistentstorage); - StructureTemplateManager structuretemplatemanager = server.getStructureManager(); - int j = server.getPlayerList().getViewDistance(); @@ -279,16 +279,17 @@ }); + this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -+ + + // Paper start + @Override + public boolean hasChunk(int chunkX, int chunkZ) { + return this.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ) != null; + } + // Paper end - ++ /** @deprecated */ @Deprecated + @VisibleForTesting @@ -273,8 +435,8 @@ this.serverLevelData.setClearWeatherTime(clearDuration); this.serverLevelData.setRainTime(rainDuration); @@ -430,7 +431,14 @@ BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos); Optional optional = this.findLightningRod(blockposition1); -@@ -582,6 +760,7 @@ +@@ -576,12 +754,13 @@ + } else { + AABB axisalignedbb = AABB.encapsulatingFullBlocks(blockposition1, blockposition1.atY(this.getMaxY() + 1)).inflate(3.0D); + List list = this.getEntitiesOfClass(LivingEntity.class, axisalignedbb, (entityliving) -> { +- return entityliving != null && entityliving.isAlive() && this.canSeeSky(entityliving.blockPosition()); ++ return entityliving != null && entityliving.isAlive() && this.canSeeSky(entityliving.blockPosition()) && !entityliving.isSpectator(); // Paper - Fix lightning being able to hit spectators (MC-262422) + }); + if (!list.isEmpty()) { return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition(); } else { diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index 489969bd2d..dd503ea9fa 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -63,6 +63,7 @@ - return false; + return null; // Paper - Expand PlayerGameModeChangeEvent } else { +- this.setGameModeForPlayer(gameMode, this.previousGameModeForPlayer); + // CraftBukkit start + PlayerGameModeChangeEvent event = new PlayerGameModeChangeEvent(this.player.getBukkitEntity(), GameMode.getByValue(gameMode.getId()), cause, cancelMessage); // Paper + this.level.getCraftServer().getPluginManager().callEvent(event); @@ -70,7 +71,7 @@ + return event; // Paper - Expand PlayerGameModeChangeEvent + } + // CraftBukkit end - this.setGameModeForPlayer(gameMode, this.previousGameModeForPlayer); ++ this.setGameModeForPlayer(gameMode, this.gameModeForPlayer); // Paper - Fix MC-259571 this.player.onUpdateAbilities(); - this.player.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player)); + this.player.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit @@ -134,9 +135,9 @@ + // Update any tile entity data for this block + capturedBlockEntity = true; // Paper - Send block entities after destroy prediction + // CraftBukkit end -+ return; -+ } -+ + return; + } + + // CraftBukkit start + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, direction, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND); + if (event.isCancelled()) { @@ -144,10 +145,10 @@ + this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); + // Update any tile entity data for this block + capturedBlockEntity = true; // Paper - Send block entities after destroy prediction - return; - } ++ return; ++ } + // CraftBukkit end - ++ if (this.isCreative()) { this.destroyAndAck(pos, sequence, "creative destroy"); return; diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index c11a86084a..97590df199 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -48,7 +48,7 @@ import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; -@@ -192,11 +196,72 @@ +@@ -192,12 +196,73 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; @@ -59,7 +59,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; +import org.bukkit.NamespacedKey; import org.slf4j.Logger; -+ + +// CraftBukkit start +import io.papermc.paper.adventure.ChatProcessor; // Paper +import io.papermc.paper.adventure.PaperAdventure; // Paper @@ -118,9 +118,10 @@ +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.SmithingInventory; +// CraftBukkit end - ++ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener { + static final Logger LOGGER = LogUtils.getLogger(); @@ -212,7 +277,9 @@ private int tickCount; private int ackBlockChangesUpTo = -1; @@ -323,7 +324,7 @@ boolean flag1 = entity.verticalCollisionBelow; if (entity instanceof LivingEntity) { -@@ -449,20 +599,73 @@ +@@ -449,19 +599,72 @@ d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean flag2 = false; @@ -342,8 +343,8 @@ + this.player.absMoveTo(d0, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit this.send(ClientboundMoveVehiclePacket.fromEntity(entity)); return; - } - ++ } ++ + // CraftBukkit start - fire PlayerMoveEvent + Player player = this.getCraftPlayer(); + if (!this.hasMoved) { @@ -392,12 +393,11 @@ + this.justTeleported = false; + return; + } -+ } + } + // CraftBukkit end -+ + this.player.serverLevel().getChunkSource().move(this.player); entity.recordMovementThroughBlocks(new Vec3(d0, d1, d2), entity.position()); - Vec3 vec3d = new Vec3(entity.getX() - d0, entity.getY() - d1, entity.getZ() - d2); @@ -489,16 +692,17 @@ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (packet.getId() == this.awaitingTeleport) { @@ -1131,7 +1131,7 @@ InteractionResult enuminteractionresult = this.player.gameMode.useItemOn(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock); if (enuminteractionresult.consumesAction()) { -@@ -1257,7 +1885,7 @@ +@@ -1257,11 +1885,11 @@ } else if (enuminteractionresult instanceof InteractionResult.Success) { InteractionResult.Success enuminteractionresult_d = (InteractionResult.Success) enuminteractionresult; @@ -1140,6 +1140,11 @@ this.player.swing(enumhand, true); } } +- } ++ } else { this.player.containerMenu.sendAllDataToRemote(); } // Paper - Fix inventory desync; MC-99075 + } else { + MutableComponent ichatmutablecomponent1 = Component.translatable("build.tooHigh", i).withStyle(ChatFormatting.RED); + @@ -1281,6 +1909,8 @@ @Override public void handleUseItem(ServerboundUseItemPacket packet) { @@ -1436,10 +1441,12 @@ } return optional; -@@ -1566,6 +2324,127 @@ - return false; - } +@@ -1564,8 +2322,129 @@ + } + return false; ++ } ++ + // CraftBukkit start - add method + public void chat(String s, PlayerChatMessage original, boolean async) { + if (s.isEmpty() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { @@ -1532,8 +1539,8 @@ + this.server.console.sendMessage(s); + } + } -+ } -+ + } + + private void handleCommand(String s) { + org.spigotmc.AsyncCatcher.catchOp("Command Dispatched Async: " + s); // Paper - Add async catcher + if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot diff --git a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch index 07d1a19fba..e712291963 100644 --- a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch @@ -180,7 +180,7 @@ + } + if (optional.isEmpty() || invalidPlayerWorld[0]) { + // Paper end - reset to main world spawn if first spawn or invalid world -+ player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); ++ player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), worldserver1.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored + } + // Paper end - Entity#getEntitySpawnReason player.setServerLevel(worldserver1); @@ -391,7 +391,7 @@ if (advancementdataplayer != null) { advancementdataplayer.save(); -@@ -334,95 +519,207 @@ +@@ -334,95 +519,209 @@ } @@ -560,8 +560,10 @@ + Player player = entity.getBukkitEntity(); + PlayerLoginEvent event = new PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress()); + -+ if (this.bans.isBanned(gameprofile)) { -+ UserBanListEntry gameprofilebanentry = (UserBanListEntry) this.bans.get(gameprofile); ++ // Paper start - Fix MC-158900 ++ UserBanListEntry gameprofilebanentry; ++ if (this.bans.isBanned(gameprofile) && (gameprofilebanentry = this.bans.get(gameprofile)) != null) { ++ // Paper end - Fix MC-158900 + ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason()); if (gameprofilebanentry.getExpires() != null) { @@ -587,11 +589,10 @@ } - return ichatmutablecomponent; -- } else { -- return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(profile) ? Component.translatable("multiplayer.disconnect.server_full") : null; + // return chatmessage; + event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure -+ } else { + } else { +- return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(profile) ? Component.translatable("multiplayer.disconnect.server_full") : null; + // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; + if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) { + event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure @@ -638,7 +639,7 @@ if (entityplayer1 != null) { set.add(entityplayer1); -@@ -431,72 +728,160 @@ +@@ -431,72 +730,160 @@ Iterator iterator1 = set.iterator(); while (iterator1.hasNext()) { @@ -820,7 +821,7 @@ return entityplayer1; } -@@ -516,15 +901,32 @@ +@@ -516,15 +903,32 @@ } public void sendPlayerPermissionLevel(ServerPlayer player) { @@ -855,14 +856,10 @@ this.sendAllPlayerInfoIn = 0; } -@@ -537,9 +939,28 @@ - ServerPlayer entityplayer = (ServerPlayer) iterator.next(); +@@ -541,6 +945,25 @@ + + } - entityplayer.connection.send(packet); -+ } -+ -+ } -+ + // CraftBukkit start - add a world/entity limited version + public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) { + for (int i = 0; i < this.players.size(); ++i) { @@ -877,14 +874,15 @@ + public void broadcastAll(Packet packet, Level world) { + for (int i = 0; i < world.players().size(); ++i) { + ((ServerPlayer) world.players().get(i)).connection.send(packet); - } - - } ++ } ++ ++ } + // CraftBukkit end - ++ public void broadcastAll(Packet packet, ResourceKey dimension) { Iterator iterator = this.players.iterator(); -@@ -554,7 +975,7 @@ + +@@ -554,7 +977,7 @@ } @@ -893,7 +891,7 @@ PlayerTeam scoreboardteam = source.getTeam(); if (scoreboardteam != null) { -@@ -573,7 +994,7 @@ +@@ -573,7 +996,7 @@ } } @@ -902,7 +900,7 @@ PlayerTeam scoreboardteam = source.getTeam(); if (scoreboardteam == null) { -@@ -619,7 +1040,7 @@ +@@ -619,7 +1042,7 @@ } public void deop(GameProfile profile) { @@ -911,7 +909,7 @@ ServerPlayer entityplayer = this.getPlayer(profile.getId()); if (entityplayer != null) { -@@ -629,6 +1050,11 @@ +@@ -629,6 +1052,11 @@ } private void sendPlayerPermissionLevel(ServerPlayer player, int permissionLevel) { @@ -923,7 +921,7 @@ if (player.connection != null) { byte b0; -@@ -643,36 +1069,53 @@ +@@ -643,36 +1071,53 @@ player.connection.send(new ClientboundEntityEventPacket(player, b0)); } @@ -990,7 +988,7 @@ if (entityplayer != player && entityplayer.level().dimension() == worldKey) { double d4 = x - entityplayer.getX(); double d5 = y - entityplayer.getY(); -@@ -687,10 +1130,12 @@ +@@ -687,10 +1132,12 @@ } public void saveAll() { @@ -1003,7 +1001,7 @@ } public UserWhiteList getWhiteList() { -@@ -712,15 +1157,19 @@ +@@ -712,15 +1159,19 @@ public void reloadWhiteList() {} public void sendLevelInfo(ServerPlayer player, ServerLevel world) { @@ -1027,7 +1025,7 @@ } player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F)); -@@ -729,8 +1178,16 @@ +@@ -729,8 +1180,16 @@ public void sendAllPlayerInfo(ServerPlayer player) { player.inventoryMenu.sendAllDataToRemote(); @@ -1045,7 +1043,7 @@ } public int getPlayerCount() { -@@ -746,6 +1203,7 @@ +@@ -746,6 +1205,7 @@ } public void setUsingWhiteList(boolean whitelistEnabled) { @@ -1053,7 +1051,7 @@ this.doWhiteList = whitelistEnabled; } -@@ -786,12 +1244,36 @@ +@@ -786,12 +1246,36 @@ } public void removeAll() { @@ -1092,7 +1090,7 @@ public void broadcastSystemMessage(Component message, boolean overlay) { this.broadcastSystemMessage(message, (entityplayer) -> { return message; -@@ -819,24 +1301,43 @@ +@@ -819,24 +1303,43 @@ } public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound params) { @@ -1139,7 +1137,7 @@ } if (flag1 && sender != null) { -@@ -845,20 +1346,27 @@ +@@ -845,20 +1348,27 @@ } @@ -1172,7 +1170,7 @@ Path path = file2.toPath(); if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) { -@@ -867,7 +1375,7 @@ +@@ -867,7 +1377,7 @@ } serverstatisticmanager = new ServerStatsCounter(this.server, file1); @@ -1181,7 +1179,7 @@ } return serverstatisticmanager; -@@ -875,13 +1383,13 @@ +@@ -875,13 +1385,13 @@ public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) { UUID uuid = player.getUUID(); @@ -1197,7 +1195,7 @@ } advancementdataplayer.setPlayer(player); -@@ -932,15 +1440,28 @@ +@@ -932,15 +1442,28 @@ } public void reloadResources() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java.patch index 6dda582ccb..8323bfa7ee 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java +++ b/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java -@@ -72,6 +72,12 @@ +@@ -72,9 +72,16 @@ } if (this.breakTime == this.getDoorBreakTime() && this.isValidDifficulty(this.mob.level().getDifficulty())) { @@ -10,6 +10,11 @@ + return; + } + // CraftBukkit end ++ final net.minecraft.world.level.block.state.BlockState oldState = this.mob.level().getBlockState(this.doorPos); // Paper - fix MC-263999 this.mob.level().removeBlock(this.doorPos, false); this.mob.level().levelEvent(1021, this.doorPos, 0); - this.mob.level().levelEvent(2001, this.doorPos, Block.getId(this.mob.level().getBlockState(this.doorPos))); +- this.mob.level().levelEvent(2001, this.doorPos, Block.getId(this.mob.level().getBlockState(this.doorPos))); ++ this.mob.level().levelEvent(2001, this.doorPos, Block.getId(oldState)); // Paper - fix MC-263999 + } + + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/EatBlockGoal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/EatBlockGoal.java.patch index 0dd16a1ddc..72de1e0703 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/EatBlockGoal.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/EatBlockGoal.java.patch @@ -11,7 +11,19 @@ public class EatBlockGoal extends Goal { private static final int EAT_ANIMATION_TICKS = 40; -@@ -63,8 +67,9 @@ +@@ -27,6 +31,11 @@ + + @Override + public boolean canUse() { ++ // Paper start - Fix MC-210802 ++ if (!((net.minecraft.server.level.ServerLevel) this.level).chunkSource.chunkMap.anyPlayerCloseEnoughForSpawning(this.mob.chunkPosition())) { ++ return false; ++ } ++ // Paper end + if (this.mob.getRandom().nextInt(this.mob.isBaby() ? 50 : 1000) != 0) { + return false; + } else { +@@ -63,8 +72,9 @@ if (this.eatAnimationTick == this.adjustedTickDelay(4)) { BlockPos blockposition = this.mob.blockPosition(); @@ -23,7 +35,7 @@ this.level.destroyBlock(blockposition, false); } -@@ -73,7 +78,7 @@ +@@ -73,7 +83,7 @@ BlockPos blockposition1 = blockposition.below(); if (this.level.getBlockState(blockposition1).is(Blocks.GRASS_BLOCK)) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch new file mode 100644 index 0000000000..885e0fd98c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/SwellGoal.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/world/entity/ai/goal/SwellGoal.java ++++ b/net/minecraft/world/entity/ai/goal/SwellGoal.java +@@ -21,7 +21,14 @@ + return this.creeper.getSwellDir() > 0 || livingEntity != null && this.creeper.distanceToSqr(livingEntity) < 9.0; + } + ++ // Paper start - Fix MC-179072 + @Override ++ public boolean canContinueToUse() { ++ return !net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(this.creeper.getTarget()) && canUse(); ++ } ++ // Paper end ++ ++ @Override + public void start() { + this.creeper.getNavigation().stop(); + this.target = this.creeper.getTarget(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch index 4f592f1a05..3084a4832d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch @@ -21,7 +21,7 @@ } @Override -@@ -229,8 +234,15 @@ +@@ -229,15 +234,23 @@ ItemStack itemstack = player.getItemInHand(hand); if (itemstack.is(Items.BUCKET) && !this.isBaby()) { @@ -38,7 +38,16 @@ player.setItemInHand(hand, itemstack1); return InteractionResult.SUCCESS; -@@ -353,8 +365,7 @@ + } else { ++ boolean isFood = this.isFood(itemstack); // Paper - track before stack is possibly decreased to 0 (Fixes MC-244739) + InteractionResult enuminteractionresult = super.mobInteract(player, hand); + +- if (enuminteractionresult.consumesAction() && this.isFood(itemstack)) { ++ if (enuminteractionresult.consumesAction() && isFood) { // Paper + this.playEatingSound(); + } + +@@ -353,8 +366,7 @@ double d2 = (double) Mth.randomBetween(this.random, -0.2F, 0.2F); ItemEntity entityitem = new ItemEntity(this.level(), vec3d.x(), vec3d.y(), vec3d.z(), itemstack, d0, d1, d2); @@ -48,7 +57,7 @@ } } -@@ -383,4 +394,15 @@ +@@ -383,4 +395,15 @@ public static boolean checkGoatSpawnRules(EntityType entityType, LevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) { return world.getBlockState(pos.below()).is(BlockTags.GOATS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch index 22924ee11b..f6ea12c8e6 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch @@ -57,7 +57,23 @@ this.dropItem(world, source.getEntity(), false); this.gameEvent(GameEvent.BLOCK_CHANGE, source.getEntity()); this.playSound(this.getRemoveItemSound(), 1.0F, 1.0F); -@@ -267,17 +286,23 @@ +@@ -251,7 +270,15 @@ + + public ItemStack getItem() { + return (ItemStack) this.getEntityData().get(ItemFrame.DATA_ITEM); ++ } ++ ++ // Paper start - Fix MC-123848 (spawn item frame drops above block) ++ @Nullable ++ @Override ++ public net.minecraft.world.entity.item.ItemEntity spawnAtLocation(ServerLevel serverLevel, ItemStack stack) { ++ return this.spawnAtLocation(serverLevel, stack, this.getDirection() == Direction.DOWN ? -0.6F : 0.0F); + } ++ // Paper end + + @Nullable + public MapId getFramedMapId(ItemStack stack) { +@@ -267,17 +294,23 @@ } public void setItem(ItemStack value, boolean update) { @@ -87,7 +103,7 @@ this.level().updateNeighbourForOutputSignal(this.pos, Blocks.AIR); } -@@ -386,7 +411,13 @@ +@@ -386,7 +419,13 @@ if (worldmap != null && worldmap.isTrackedCountOverLimit(256)) { return InteractionResult.FAIL; } else { @@ -102,7 +118,7 @@ this.gameEvent(GameEvent.BLOCK_CHANGE, player); itemstack.consume(1, player); return InteractionResult.SUCCESS; -@@ -395,6 +426,13 @@ +@@ -395,6 +434,13 @@ return InteractionResult.PASS; } } else { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/npc/CatSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/npc/CatSpawner.java.patch new file mode 100644 index 0000000000..6d93d621f8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/npc/CatSpawner.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/entity/npc/CatSpawner.java ++++ b/net/minecraft/world/entity/npc/CatSpawner.java +@@ -82,8 +82,8 @@ + if (cat == null) { + return 0; + } else { ++ cat.moveTo(pos, 0.0F, 0.0F); // Paper - move up - Fix MC-147659 + cat.finalizeSpawn(world, world.getCurrentDifficultyAt(pos), EntitySpawnReason.NATURAL, null); +- cat.moveTo(pos, 0.0F, 0.0F); + world.addFreshEntityWithPassengers(cat); + return 1; + } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/BeaconMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/BeaconMenu.java.patch index 3875eea7ad..7034563131 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/BeaconMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/BeaconMenu.java.patch @@ -43,7 +43,7 @@ return stillValid(this.access, player, Blocks.BEACON); } -@@ -148,12 +157,25 @@ +@@ -148,12 +157,30 @@ return BeaconMenu.decodeEffect(this.beaconData.get(2)); } @@ -54,6 +54,11 @@ + // Paper end - Add PlayerChangeBeaconEffectEvent + public void updateEffects(Optional> primary, Optional> secondary) { ++ // Paper start - fix MC-174630 - validate secondary power ++ if (secondary.isPresent() && secondary.get() != net.minecraft.world.effect.MobEffects.REGENERATION && (primary.isPresent() && secondary.get() != primary.get())) { ++ secondary = Optional.empty(); ++ } ++ // Paper end if (this.paymentSlot.hasItem()) { - this.beaconData.set(1, BeaconMenu.encodeEffect((Holder) primary.orElse((Object) null))); - this.beaconData.set(2, BeaconMenu.encodeEffect((Holder) secondary.orElse((Object) null))); @@ -71,7 +76,7 @@ } } -@@ -178,4 +200,17 @@ +@@ -178,4 +205,17 @@ return 1; } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch index 18e45c40c5..67743248ac 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch @@ -20,10 +20,11 @@ if (world instanceof ServerLevel worldserver) { if (entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) { - entity.clearFire(); +- if (entity.mayInteract(worldserver, pos)) { +- this.handleEntityOnFireInside(state, world, pos); + // CraftBukkit start - moved down + // entity.clearFire(); - if (entity.mayInteract(worldserver, pos)) { -- this.handleEntityOnFireInside(state, world, pos); ++ if ((entity instanceof net.minecraft.world.entity.player.Player || worldserver.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(worldserver, pos)) { // Paper - Fixes MC-248588 + if (this.handleEntityOnFireInsideWithEvent(state, world, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities + entity.clearFire(); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch index b6b9a83fe6..b01d0e52a4 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch @@ -276,7 +276,7 @@ } } -@@ -378,30 +481,47 @@ +@@ -378,41 +481,55 @@ } public List> getRecipesToAwardAndPopExperience(ServerLevel world, Vec3 pos) { @@ -330,3 +330,18 @@ } @Override + public void fillStackedContents(StackedItemContents finder) { +- Iterator iterator = this.items.iterator(); ++ // Paper start - don't account fuel stack (fixes MC-243057) ++ finder.accountStack(this.items.get(SLOT_INPUT)); ++ finder.accountStack(this.items.get(SLOT_RESULT)); ++ // Paper end + +- while (iterator.hasNext()) { +- ItemStack itemstack = (ItemStack) iterator.next(); +- +- finder.accountStack(itemstack); +- } +- + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch index 35f0ee8e2d..83c5809644 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch @@ -77,7 +77,7 @@ if (blockEntity.lastCheckY >= l) { blockEntity.lastCheckY = world.getMinY() - 1; -@@ -247,43 +291,104 @@ +@@ -247,43 +291,108 @@ @Override public void setRemoved() { @@ -85,7 +85,11 @@ + org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, worldPosition); + new io.papermc.paper.event.block.BeaconDeactivatedEvent(block).callEvent(); + // Paper end - beacon activation/deactivation events ++ // Paper start - fix MC-153086 ++ if (this.levels > 0 && !this.beamSections.isEmpty()) { BeaconBlockEntity.playSound(this.level, this.worldPosition, SoundEvents.BEACON_DEACTIVATE); ++ } ++ // Paper end super.setRemoved(); } @@ -197,7 +201,7 @@ public static void playSound(Level world, BlockPos pos, SoundEvent sound) { world.playSound((Player) null, pos, sound, SoundSource.BLOCKS, 1.0F, 1.0F); } -@@ -316,7 +421,7 @@ +@@ -316,7 +425,7 @@ if (nbt.contains(key, 8)) { ResourceLocation minecraftkey = ResourceLocation.tryParse(nbt.getString(key)); @@ -206,7 +210,7 @@ } else { return null; } -@@ -327,11 +432,13 @@ +@@ -327,11 +436,13 @@ super.loadAdditional(nbt, registries); this.primaryPower = BeaconBlockEntity.loadEffect(nbt, "primary_effect"); this.secondaryPower = BeaconBlockEntity.loadEffect(nbt, "secondary_effect"); @@ -220,7 +224,7 @@ } @Override -@@ -345,6 +452,7 @@ +@@ -345,6 +456,7 @@ } this.lockKey.addToTag(nbt, registries); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch index 9bcacf4e23..e58a4bb1dc 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch @@ -52,3 +52,12 @@ ObjectListIterator objectlistiterator = objectarraylist.iterator(); while (objectlistiterator.hasNext()) { +@@ -370,7 +391,7 @@ + } + + public void overrideEntityToSpawn(EntityType entityType, Level world) { +- this.data.reset(); ++ this.data.reset(this); // Paper + this.normalConfig = Holder.direct(((TrialSpawnerConfig) this.normalConfig.value()).withSpawning(entityType)); + this.ominousConfig = Holder.direct(((TrialSpawnerConfig) this.ominousConfig.value()).withSpawning(entityType)); + this.setState(world, TrialSpawnerState.INACTIVE); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch index 20b5f75633..9f48f83f27 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch @@ -1,5 +1,17 @@ --- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java +++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java +@@ -100,9 +100,9 @@ + this.ejectingLootTable = rewardLootTable; + } + +- public void reset() { ++ public void reset(TrialSpawner logic) { // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 + this.currentMobs.clear(); +- this.nextSpawnData = Optional.empty(); ++ if (!logic.getConfig().spawnPotentialsDefinition().isEmpty()) this.nextSpawnData = Optional.empty(); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 + this.resetStatistics(); + } + @@ -210,7 +210,7 @@ } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java.patch new file mode 100644 index 0000000000..293d3ea411 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java ++++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java +@@ -145,7 +145,7 @@ + yield ACTIVE; + } else if (trialSpawnerData.isCooldownFinished(world)) { + logic.removeOminous(world, pos); +- trialSpawnerData.reset(); ++ trialSpawnerData.reset(logic); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 + yield WAITING_FOR_PLAYERS; + } else { + yield this; diff --git a/paper-server/patches/sources/net/minecraft/world/level/portal/TeleportTransition.java.patch b/paper-server/patches/sources/net/minecraft/world/level/portal/TeleportTransition.java.patch index 1733056573..1d72cf288c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/portal/TeleportTransition.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/portal/TeleportTransition.java.patch @@ -53,10 +53,19 @@ } + public TeleportTransition(ServerLevel worldserver, Entity entity, TeleportTransition.PostTeleportTransition teleporttransition_a, PlayerTeleportEvent.TeleportCause cause) { -+ this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, 0.0F, 0.0F, false, false, Set.of(), teleporttransition_a, cause); ++ this(worldserver, findAdjustedSharedSpawnPos(worldserver, entity), Vec3.ZERO, worldserver.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), teleporttransition_a, cause); // Paper - MC-200092 - fix first spawn pos yaw being ignored + // CraftBukkit end + } + private static void playPortalSound(Entity entity) { if (entity instanceof ServerPlayer entityplayer) { entityplayer.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false)); +@@ -40,7 +69,7 @@ + } + + public static TeleportTransition missingRespawnBlock(ServerLevel world, Entity entity, TeleportTransition.PostTeleportTransition postDimensionTransition) { +- return new TeleportTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, 0.0F, 0.0F, true, false, Set.of(), postDimensionTransition); ++ return new TeleportTransition(world, findAdjustedSharedSpawnPos(world, entity), Vec3.ZERO, world.getSharedSpawnAngle(), 0.0F, true, false, Set.of(), postDimensionTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored + } + + private static Vec3 findAdjustedSharedSpawnPos(ServerLevel world, Entity entity) {